Djangoroidの奮闘記

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

Django REST Frameworkに再挑戦 その24 Django Rest Framework JWT & Curl Tests

概要

Django REST Frameworkに再挑戦 その24 Django Rest Framework JWT & Curl Tests

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

Django Rest Framework JWT & Curl Tests

  • Django Rest Framework JWTの公式ページをチェックしてみる。認証関連のpackage。JSON Web Token Authentication support for Django REST framework.らしい。

Django REST framework JWT

  • $ pip install djangorestframework-jwtする。

  • settings.pyのREST FRAMEWORKの設定に以下のように追記する。

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    # 'DEFAULT_PARSER_CLASSES': (
    #     'rest_framework.parsers.JSONParser',
    # ),
    'DEFAULT_AUTHENTICATION_CLASSES':(
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication', #'rest_framework.authentication.BasicAuthentication', #こちらはオススメしないとのこと。
    ),
    'DEFAULT_PERMISSION_CLASSES':(
        'rest_framework.permissions.IsAuthenticated',
    ),

}
  • rest_framework.authentication.SessionAuthenticationコメントアウトしてもOK。

  • urls.pyに、JWT用のurlを設定する。

from rest_framework_jwt.views import obtain_jwt_token
#...

urlpatterns = patterns(
    '',
    # ...

    url(r'^api/auth/token/', obtain_jwt_token), # urlの箇所だけ微妙に変えてある。
)
  • テスト用のshell スクリプトも用意されているので、settings.pyなどにメモっておく。
'''
You can easily test if the endpoint is working by doing the following in your terminal, if you had a user created with the username admin and password password123.

$ curl -X POST -d "username=user名&password=********" http://127.0.0.1:8000/api/auth/token/
'''
  • シェルで、$ curl -X POST -d "username=user名&password=********" http://127.0.0.1:8000/api/auth/token/ を打って、tokenが表示されたらOK。

  • テストとして、シェルに表示されたtokenをメモっておき、次のテストに使う。

  • 先ずは、curl http://127.0.0.1:8000/api/comments/ としておき、認証が必要なサイトに行ってみる。。。{"detail":"Authentication credentials were not provided."}と表示されたので、取得できなかったことがわかる。

  • 次に、$ curl -H "Authorization: JWT <your_token>" http://127.0.0.1:8000/api/comments/でアクセスしてみる。。。取得できた〜〜!

  • さらに、commentの投稿も試してみる。ヘッダー2つで、パスとコンテンツ部分を渡す。

curl -X POST -H "Authorization: JWT ***********************************.*********************************.-1XWtO99XlA75fahKjLdSLxfa3f6kbDo1qpcCmUTopE" -H "Content-Type: application/json" -d '{"content":"this is content"}' 'http://127.0.0.1:8000/api/comments/create/?slug=my-title&type=post'
  • さらに、parent_idでスレッドにもコメントできるか確認する。
curl -X POST -H "Authorization: JWT ***********************************.*********************************.-1XWtO99XlA75fahKjLdSLxfa3f6kbDo1qpcCmUTopE" -H "Content-Type: application/json" -d '{"content":"this is content"}' 'http://127.0.0.1:8000/api/comments/create/?slug=my-title&type=post&parent_id'
  • これは便利やな〜!

Django REST Frameworkに再挑戦 その23 Django Rest Framework Settings

概要

Django REST Frameworkに再挑戦 その23 Django Rest Framework Settings

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

Django Rest Framework Settings

  • Django Rest Frame WorkのSettingsについて見てみる。

Settings - Django REST framework

  • settings.pyに、追記する。
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.JSONParser',
    )
}
  • Classesの箇所は、タプル形式になっているので、追記できる。 'rest_framework.renderers.BrowsableAPIRenderer'もデフォルトで設定されている。手動で設定する場合は、以下のような形で挿入する。
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.JSONParser',
    ),
}
  • DEFAULT_AUTHENTICATION_CLASSESの設定をする。
    'DEFAULT_AUTHENTICATION_CLASSES':(
        'rest_framework.authentication.SessionAuthentication',
        # 'rest_framework.authentication.BasicAuthentication', #こちらはオススメしないとのこと。
    ),
  • DEFAULT_PERMISSION_CLASSESの設定をする。
    'DEFAULT_PERMISSION_CLASSES':(
        'rest_framework.permissions.AllowAny',
    )
  • 例えば、IsAuthenticatedをデフォルトにしたい場合は、以下のように設定する。
    'DEFAULT_PERMISSION_CLASSES':(
        'rest_framework.permissions.IsAuthenticated',
    ),
  • その場合、デフォルトのpermission_classesが、IsAuthenticatedになるため、各APIViewのpermission_classesを修正していく。

Django REST Frameworkに再挑戦 その22 User Detail Serailizer

概要

Django REST Frameworkに再挑戦 その22 User Detail Serailizer

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

User Detail Serailizer

  • user detailのAPIViewを作成したい。そしてそれをcommentsのdetailViewに表示させたい。まず、accounts/api/serializers.pyにコードを追記する。
class UserDetailSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = [
            'username',
            'email',
            'first_name',
            'last_name',
        ]
  • 次に、comments/api/serializers.pyにUserDetailSerializerをimportする。
from accounts.api.serializers import UserDetailSerializer
...
class CommentChildSerializer(ModelSerializer):
    user = UserDetailSerializer()
...
class CommentDetailSerializer(ModelSerializer):
    user = UserDetailSerializer()
...
  • このままでは、comment api viewからuserの編集ができてしまうので、read_only=Trueを追記しておく。
user = UserDetailSerializer(read_only=True)
  • post/api/serializers.pyのuserの箇所も同様に、user = UserDetailSerializer(read_only=True)に置き換えておく。

Django REST Frameworkに再挑戦 その21 UserLogin API Validation

概要

Django REST Frameworkに再挑戦 その21 UserLogin API Validation

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

UserLogin API Validation

  • accounts/api/serializers.pyのUserLoginSerializer に、validationをつける。
class UserLoginSerializer(ModelSerializer):
...

    def validate(self, data):
        user_obj = None
        email = data.get("email", None)
        username = data.get("email", None)
        password = data["password"]
        if not email or not username:
            raise ValidationError("A username or email is required to login.")

        user = User.objects.filter(
                Q(email=email) |
                Q(username=username)
            ).distinct()

        if user.exists() and user.count() == 1:
            user_obj = user.first()
        else:
            raise ValidationError("ユーザー、emailが存在しません。")

        if  user_obj:
            if not user_obj.check_password(password):
                raise ValidationError("パスワードが正しくありません。")

        data["token"] = "SOME RANDOM TOKEN"

        return data
  • ただ、このvalidationでは、emailが登録されてない人たちがリストとして表示されてしまうので、以下の一文を差し込む。これは、nullと、"(空欄)"のリストを除くという意味だと思う。
user = user.exclude(email__isnull=True).exclude(email__iexact='')
  • これでログイン実装完了か〜、この辺は、ライブラリの利用が必要なきがするな。

Django REST Frameworkに再挑戦 その20 Base APIView for User Login

概要

Django REST Frameworkに再挑戦 その20 Base APIView for User Login

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

Base APIView for User Login

  • UserLoginSerializerというclassを新たに作成する。
class UserLoginSerializer(ModelSerializer):
    token = CharField(allow_blank=True, read_only=True)
    username = CharField()
    email = EmailField(label='Email Address')
    class Meta:
        model = User
        fields = [
            'username',
            'email',
            'password',
            'token',
        ]
        extra_kwargs = {"password":
                            {"write_only": True}
                            }

    def validate(self, data):
    #     email = data['email']
    #     user_qs = User.objects.filter(email=email)
    #     if user_qs.exists():
    #         raise ValidationError("すでにこちらのアドレスは登録されています。")
        return data
  • accounts/api/views.pyにLoginViewを作成する。
class UserLoginAPIView(APIView):
    permission_classes = [AllowAny]
    serializer_class = UserLoginSerializer

    def post(self, request, *args, **kwargs):
        data = request.data # request.POST
        serializer = UserLoginSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            new_data = serializer.data
            return Response(new_data, status=HttP_200_OK) # ここのresponseは、rest_frameworkのAPIなので注意。
        return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

Django REST Frameworkに再挑戦 その19 Serializer Validation

概要

Django REST Frameworkに再挑戦 その19 Serializer Validation

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

Serializer Validation

  • serializers.pyにコードを追記する。
...
class UserCreateSerializer(ModelSerializer):
    email = serializers.EmailField(label='Email Address') #emailフィールドのserializerによる上書き
    email2 = serializers.EmailField(label='Confirm Email') #confirm用のフィールド。
    class Meta:
        model = User
        fields = [
            'username',
            'email',
            'email2',
            'password',
        ]
        extra_kwargs = {"password":
                            {"write_only": True}
                            }

    def validate_email2(self, value):#validate_フィールド名で、validationをセットできるぽい。
        data = self.get_initial() 
        email1 = data.get("email")
        email2 = value
        if email1 != email2:
            raise ValidationError("Emailが一致していません。")
        return value
....
  • 次は、重複したemailの登録がないかをvalidateする。
    def validate(self, data):
        email = data['email']
        user_qs = User.objects.filter(email=email)
        if user_qs.exists():
            raise ValidationError("すでにこちらのアドレスは登録されています。")
        return data
  • これをvalidate_emailに含める。
    def validate_email(self, value):#validate_フィールド名で、validationをセットできるぽい。
        data = self.get_initial()
        email1 = data.get("email2")
        email2 = value
        if email1 != email2:
            raise ValidationError("Emailが一致していません。")

        user_qs = User.objects.filter(email=email2)
        if user_qs.exists():
            raise ValidationError("すでにこちらのアドレスは登録されています。")

        return value

Django REST Frameworkに再挑戦 その19 ModelSerializer Create Method

概要

Django REST Frameworkに再挑戦 その19 ModelSerializer Create Method

参考サイト

www.django-rest-framework.org

www.codingforentrepreneurs.com

ModelSerializer Create Method

  • account/api/serializers.py にコードを追記する。
class UserCreateSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = [
            'username',
            'password',
            'email',
        ]
        extra_kwargs = {"password":
                            {"write_only": True}
                            }
    def create(self, validated_data):

        return validated_data
  • これだけでは、createメソッドを上書きしているだけなので、ここに処理を加えていく。
class UserCreateSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = [
            'username',
            'email',
            'password',
        ]
        extra_kwargs = {"password":
                            {"write_only": True}
                            }
                            
    def create(self, validated_data):
        username = validated_data['username']
        email = validated_data['email']
        password = validated_data['password']
        user_obj = User(
                username = username,
                email = email,
            )
        user_obj.set_password(password)
        user_obj.save()
        return validated_data
  • これで、/api/users/register/にアクセスして、登録してみる。。。。さらに登録したuserでログインしてみる。。。できた〜!