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"),

참고 사이트

아래 글은 한번 정독을 권고!!

[
Deep Dive into Class-Based Views — Python 401 2.1 documentation
![](assets/images/2023/02/cf_logo.png?ssl=1)
](https://codefellows.github.io/sea-python-401d5/lectures/django_cbv2.html#the-get-object-method)

장고 소스도 읽어보자. 오버라이딩 하려면 먼가 알아야징

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
author-profile
Written by bj