2017-08-22 12 views
0

私のDjangoプロジェクトでトークンが生成されないのはなぜかと思います。私は自分のデータベースをチェックし、何のトークンがありませんトークンが生成されない理由を知っている人は誰ですか?

django_1 | Traceback (most recent call last): 
django_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner 
django_1 |  response = get_response(request) 
django_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response 
django_1 |  response = self.process_exception_by_middleware(e, request) 
django_1 | File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response 
django_1 |  response = wrapped_callback(request, *callback_args, **callback_kwargs) 
django_1 | File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view 
django_1 |  return view_func(*args, **kwargs) 
django_1 | File "/usr/local/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view 
django_1 |  return self.dispatch(request, *args, **kwargs) 
django_1 | File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 489, in dispatch 
django_1 |  response = self.handle_exception(exc) 
django_1 | File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 449, in handle_exception 
django_1 |  self.raise_uncaught_exception(exc) 
django_1 | File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 486, in dispatch 
django_1 |  response = handler(request, *args, **kwargs) 
django_1 | File "/code/myProject/backend/myProject/companies/views.py", line 43, in post 
django_1 |  return Response({'token': user.auth_token.key, 'id': user.id}, status=status.HTTP_200_OK) 
django_1 | File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 404, in __get__ 
django_1 |  self.related.get_accessor_name() 
django_1 | django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist: User has no auth_token. 

:すべてが正常に働いていたが、今、私は得ることを私には思えます。明らかに私は管理パネルを介してそれを追加することができますし、それは動作しますが、もちろんそれは自動的にユーザーがサインイン時に生成する必要があります。

url(r'^login', views.UserAuthenticationView.as_view()), 

views.py:

@permission_classes([CustomPermission]) 
class UserAuthenticationView(GenericAPIView): 

    serializer_class = UserAuthenticationSerializer 

    def post(self, request, *args, **kwargs): 
     serializer = UserAuthenticationSerializer(data=self.request.data) 
     if serializer.is_valid(): 
      user = serializer.validated_data['user'] 
      return Response({'token': user.auth_token.key, 'id': user.id}, status=status.HTTP_200_OK) 
     return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED) 

serializers.py:

class UserAuthenticationSerializer(serializers.Serializer): 
    username = serializers.CharField() 
    password = serializers.CharField() 

    def validate(self, attrs): 
     username = attrs.get('username') 
     password = attrs.get('password') 

     if username and password: 
      user = authenticate(username=username, password=password) 
      if user: 

       if not user.is_active: 
        msg = 'User account is disabled.' 
        raise serializers.ValidationError(msg, code='authorization') 

      else: 
       msg = 'Unable to log in with provided credentials.' 
       raise serializers.ValidationError(msg, code='authorization') 

     else: 
      msg = 'Must include "username" and "password".' 
      raise serializers.ValidationError(msg, code='authorization') 

     attrs['user'] = user 
     return attrs 
+0

質問に「UserAuthenticationSerializer」を追加できますか? – wencakisa

+0

@wencakisa私はちょうど追加しました。 – wahtdbogh

答えて

1

あなたgetまたはcreateToken手動でする必要があります。

get_or_create方法は完璧にフィット:

from rest_framework.authtoken.models import Token 


@permission_classes([CustomPermission]) 
class UserAuthenticationView(GenericAPIView): 

    serializer_class = UserAuthenticationSerializer 

    def post(self, request, *args, **kwargs): 
     serializer = self.serializer_class(data=request.data) 
     serializer.is_valid(raise_exception=True) 

     user = serializer.validated_data['user'] 
     token, created = Token.objects.get_or_create(user=user) 

     response_data = { 
      'id': user.id, 
      'token': token.key 
     } 

     return Response(response_data, status=status.HTTP_200_OK) 

それはまだ存在しない場合は今Tokenが生成されます、またはそれが既に作成されている場合、データベースから取得されます。

:あなたはこのifステートメントを記述しないようにするためにis_valid()raise_exception=True引数を渡すことができます。

+0

ありがとう、それは動作します。あなたはトークンの有効期限を使いますか? – wahtdbogh

+0

@Wahtdboghデフォルトの 'TokenAuthentication'は期限切れをサポートしていません。しかし、あなたはこのリソースを見ることができます:https://stackoverflow.com/questions/14567586/token-authentication-for-restful-api-should-the-token-be-periodically-changed – wencakisa

+0

@Wahtdbogh私はちょうどこのパッケージが見つかりました:https://github.com/JamesRitchie/django-rest-framework-expiring-tokensこれは非常に使いやすいように見えます。 – wencakisa

関連する問題