Django e-commerce part70 Login Required Mixin
Login Required Mixinを作成する
orders/mixins.py に追記する。
from django.contrib.auth.decorators import login_required from django.utils.decorators import method_decorator class LoginRequiredMixin(object): @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
ポイント
結論的には、このclassを継承すると、継承したclassのviewは、閲覧のために、ログインが必須になる。
なぜそうなるのかは、前にもブログで書いたが、前よりもちょっと理解が進んだかもしれないので、もう一度自分なりの解釈で説明してみる。
もともと、@login_requiredは、view のfunctionなどに直接使う、関数デコレーター。例えば、以下のような感じ。
from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...
ただここでやりたいことは、class based viewのdispatchメソッドに、login_requiredを適用させるということ。なぜかというと、dispatchメソッドに、login_requiredのデコレーターを追加しておくと、そのviewのインスタンスには、全てlogin_rquiredが適用されるようになるため。(dispatchメソッドは、viewを表示する時に実行されるクラスメソッド)
ただ、login_requiredは、関数デコレーターのため、クラスメソッドには適用できない。(クラスメソッドはちょっと特殊)。そこで登場するのが、@method_decorator。
@method_decorator()は、何ができるかというと、関数デコレーター -> メソッドデコレーターに変換することができる。
メソッドデコレーターになると、クラスメソッドをデコレートできる。つまり、ここでいうと、class based viewのクラスメソッド(クラスにもともと備わっているメソッド?)である、dispatchメソッドをデコレートできるようになる。
関数デコレーター -> インスタンスメソッド、スタティックメソッド、
- メソッドデコレーター -> クラスメソッド という感じかなぁ。ちょっと自信がない。
メソッドの種類についてはこちらが非常にわかりやすいです!ありがとうございます! d.hatena.ne.jp
login_required
Djangoの認証システムを使用する | Django documentation | Django
クラスベース汎用ビュー — Django 1.4 documentation
OrderListのユーザーの絞り込みの値を修正する。
class OrderList(LoginRequiredMixin, ListView): queryset = Order.objects.all() def get_queryset(self): user_check_id = self.request.user.id user_checkout = UserCheckout.objects.get(id=user_check_id) return super(OrderList, self).get_queryset().filter(user=user_checkout)
このリストは、ログインしたユーザーしか見られないので、request.user.id でシンプルに絞り込みをかければOK。
ただ、上記だと、UserCheckoutのobjectのidと、userのidが一致しないため、以下のようにuser__idを使って絞り込みをかける。
class OrderList(LoginRequiredMixin, ListView): queryset = Order.objects.all() def get_queryset(self): user_check_id = self.request.user.id user_checkout = UserCheckout.objects.get(user__id=user_check_id) return super(OrderList, self).get_queryset().filter(user=user_checkout)