Django – UpdateView pk 있을때 없을때 다 처리하기
UpdateView pk 없이 사용하는 방법을 전 포스트에서 알아 봤는데 PK 값이 url에 있든 없든 하나의 View로 다 처리하고 싶어졌다.
일반 사용자는 자기꺼만 처리하면 되지만, superuser 혹은 admin은 다른 사용자 정보를 수정하고 싶을 수 도 있기 때문에 pk 값을 넘겨 받아서 사용하는 것도 같은 UpdateView에서 처리하고 싶었다.
그냥 get_object() 함수 내에서 pk 유무를 보고 처리하면 안되나……된다! 코드를 올려둔다.
@method_decorator(login_required, name="dispatch")class profile_update_view(UpdateView): model = Profile # fields = "__all__" fields = ["phone"] template_name = "profile.html" def get_object(self): print("profile_update_view get_object()", self.request.user, self.kwargs.get("pk")) if self.kwargs.get("pk"): if self.request.user.is_superuser: return Profile.objects.get(user=self.kwargs.get("pk")) else: set_page_message(self.request, messages.INFO, f"접근 권한이 없습니다!") return Profile.objects.get(user=self.request.user) # return self.request.user def get_success_url(self): return self.request.META["HTTP_REFERER"]
self.kwargs.get("pk")
로 pk 값이 url을 통해 넘어오는지 유무를 알수 있고 그 상황에 맞게 각자 원하는 코드를 집어 넣으면 될듯!
단!!!! urls.py 함수에서 pk 가 있는 것, 없는 것 다 같은 view를 호출하도록 꼭 해줘야 한다.
path("profile", profile_update_view.as_view(), name="profile_list_1"), path("profile/<int:pk>", profile_update_view.as_view(), name="profile_list"),
참고 사이트
아래 글은 한번 정독을 권고!!
장고 소스도 읽어보자. 오버라이딩 하려면 먼가 알아야징
slug_url_kwarg, pk_url_kwarg 를 보면 왜 ‘pk’ ‘slug’ 라는 키워드를 그냥 써도 되는지 알 수 있다. 여기에 적힌 문자열을 인식하는 것 뿐이다 😊
# django/views/generic/detail.pyclass SingleObjectMixin(ContextMixin): """ Provides the ability to retrieve a single object for further manipulation. """ model = None queryset = None slug_field = 'slug' context_object_name = None slug_url_kwarg = 'slug' pk_url_kwarg = 'pk' query_pk_and_slug = False def get_object(self, queryset=None): """ Returns the object the view is displaying. By default this requires `self.queryset` and a `pk` or `slug` argument in the URLconf, but subclasses can override this to return any object. """ # Use a custom queryset if provided; this is required for subclasses # like DateDetailView if queryset is None: queryset = self.get_queryset() # Next, try looking up by primary key. pk = self.kwargs.get(self.pk_url_kwarg, None) slug = self.kwargs.get(self.slug_url_kwarg, None) if pk is not None: queryset = queryset.filter(pk=pk) # Next, try looking up by slug. if slug is not None and (pk is None or self.query_pk_and_slug): slug_field = self.get_slug_field() queryset = queryset.filter(**{slug_field: slug}) # If none of those are defined, it's an error. if pk is None and slug is None: raise AttributeError("Generic detail view %s must be called with " "either an object pk or a slug." % self.__class__.__name__) try: # Get the single item from the filtered queryset obj = queryset.get() except queryset.model.DoesNotExist: raise Http404(_("No %(verbose_name)s found matching the query") % {'verbose_name': queryset.model._meta.verbose_name}) return obj