unk*_*own 3 django django-models django-rest-framework
错误看起来就像这样 KeyError: 'user' 而我每次显示此错误消息时都尝试登录。我已经安装了 Django Rest Framework。使用 Rest Framework 登录的最佳方法是什么?
我的看法
class LoginAPIView(APIView):
def post(self, request):
serializer = LoginSerializers(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
login(request, user)
token, created = Token.objects.get_or_create(user=user)
return Response({"status": status.HTTP_200_OK, "Token": token.key})
Run Code Online (Sandbox Code Playgroud)
我的序列化器
class LoginSerializers(serializers.Serializer):
class Meta:
model = User
email = serializers.CharField(max_length=255)
password = serializers.CharField(max_length=128, write_only=True)
def validate(self, data):
email = data.get('email', None)
password = data.get('password', None)
if email and password:
user = authenticate(username=email, password=password)
if user:
data['user'] = user
data['user'] = user
return data
Run Code Online (Sandbox Code Playgroud)
您没有引发 ValidationError。您需要重构您的序列化程序,并且如果没有用户实例,则需要引发验证错误。
from django.contrib.auth import authenticate, get_user_model
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
User = get_user_model()
class LoginSerializers(serializers.Serializer):
email = serializers.CharField(max_length=255)
password = serializers.CharField(
label=_("Password"),
style={'input_type': 'password'},
trim_whitespace=False,
max_length=128,
write_only=True
)
def validate(self, data):
username = data.get('email')
password = data.get('password')
if username and password:
user = authenticate(request=self.context.get('request'),
username=username, password=password)
if not user:
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')
data['user'] = user
return data
Run Code Online (Sandbox Code Playgroud)
在 LoginAPIView 中,您应该删除 login(request,user) 并改为使用 update_last_login(None,user)。
class LoginAPIView(APIView):
def post(self, request, *args, **kwargs):
serializer = LoginSerializers(data=request.data, context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
update_last_login(None, user)
token, created = Token.objects.get_or_create(user=user)
return Response({"status": status.HTTP_200_OK, "Token": token.key})
Run Code Online (Sandbox Code Playgroud)
如果您想要简单的事情,只需使用 django-rest-framework 提供的内置身份验证
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'token': token.key,
'user_id': user.pk,
'email': user.email
})
Run Code Online (Sandbox Code Playgroud)
您可以在这里找到更多详细信息
| 归档时间: |
|
| 查看次数: |
6591 次 |
| 最近记录: |