Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

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)