【django】ログインユーザーなのになぜか403エラーが出る時の対処法

【django】ログインユーザーなのになぜか403エラーが出る時の対処法

起こったこと

CustomerManagementViewはログインユーザーでアクセスできるのに、CustomerDetailViewはなぜか403エラーが出る。

なお、ログインしていないユーザーはログイン画面に遷移し、スーパーユーザーはDetailViewも見れるのでtemplatesなどには問題はないと考えた。

class CustomerDetailView(LoginRequiredMixin, DetaiView):
    model = Reservation
    template_name = "managements/customer_detail.html"

customer_detail = CustomerDetailView.as_view()

class CustomerManagementView(LoginRequiredMixin, ListView):
    template_name = "managements/customer_management.html"
    model = Reservation

    paginate_by = 10
    
    def get_queryset(self, **kwargs):
        queryset = Reservation.objects.order_by("-date")
        return queryset

customer_management = CustomerManagementView.as_view()


まずsettings.py、特にmiddlewareを確認したが、i18nやwhitenoise以外は追加していないので、こちらも問題なさそう。

また、管理者だけが見れる、管理画面で同じような構成のViewがあるが、こちらも問題なく見れる。

class DetailView(UserPassesTestMixin, DetailView):
    model = Reservation
    template_name = "managements/detail.html"

    def test_func(self):
        # スーパーユーザーでなければ403ページ
        return self.request.user.is_superuser
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        reservation = self.get_object()
        related_objects = reservation.changed_user.all()  # ManyToManyFieldに関連するオブジェクトのリストを取得
        context['related_objects'] = related_objects
        return context

detail = DetailView.as_view()


そのためLoginRequiredMixinに原因があると思い、UserPassesTestMixinに変更するも、以下のエラーが出る。

    class CustomerDetailView(UserPassesTestMixin, LoginRequiredMixin, DetailView):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases UserPassesTestMixin, LoginRequiredMixin, DetailView


原因と対処法

原因はDetailViewのimportにあった。

DetailViewは以下のようにimportしていて、管理画面のclass DetailView(UserPassesTestMixin, DetailView):継承したDetailViewは問題なかったが、なぜかclass CustomerDetailView(LoginRequiredMixin, DetaiView):の方はうまく継承できなかった。

from django.views.generic.detail import DetailView

こっちの形でDetailViewをimportすると後者はうまく継承できたが前者が逆に継承できなくなった。

from django.views.generic import DetailView as dt

そのため2つを分けてimportすることで解決した。なぜこのようなことが起こるのかは未だわからない。

from django.views.generic.detail import DetailView
#なぜかcustomer_detailのDetailViewだけgeneric.detailを使うとログインユーザーでも403エラーが出るのでこっちを使う(スーパーユーザーは大丈夫)
from django.views.generic import DetailView as dt



Chatgpt

from django.views.generic import DetailViewfrom django.views.generic.detail import DetailViewのどちらを使うかによってMRO(Method Resolution Order)エラーが発生するというのは興味深い現象です。通常、これらは同じクラスをインポートしているため、機能的には同じはずです。しかし、Djangoの内部実装や特定のバージョンに依存する問題があるかもしれません。

Comments

No comments yet. Why don’t you start the discussion?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です