我正在实现一个自定义用户模型,该模型具有用户和托儿所帐户。注册正在进行,但登录没有按照我预期的方式进行。此外,令牌身份验证也不起作用 我想我的观点有点不对劲,但我没办法弄明白。我在登录时遇到此错误:
AttributeError at /api/auth/login/user
Got AttributeError when attempting to get a value for field `account` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Account` instance.
Original exception text was: 'Account' object has no attribute 'account'.
这是我的模特
class AccountManager(BaseUserManager):
def create_user(self, username, email, contact, password=None):
"""Create and return a `User` with an email, username and password."""
if username is None:
raise TypeError('Users must have a username.')
if email is None:
raise TypeError('Users must have an email address.')
user = self.model(username=username,
email=self.normalize_email(email), contact=contact)
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, contact, password):
"""
Create and return a `User` with superuser (admin) permissions.
"""
if password is None:
raise TypeError('Superusers must have a password.')
user = self.create_user(username, email, contact, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
def get_by_natural_key(self, email):
return self.get(email=email)
class Account(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
contact = models.CharField(max_length=10, unique=True, default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_nursery = models.BooleanField(default=False)
is_user = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'contact']
objects = AccountManager()
def get_username(self):
return (self.username)
def __str__(self):
return self.email
class User(Account, models.Model):
account = models.OneToOneField(
Account, on_delete=models.CASCADE, primary_key=True)
full_name = models.CharField(max_length=30)
address = models.CharField(max_length=256)
class Nursery(Account, models.Model):
account = models.OneToOneField(
Account, on_delete=models.CASCADE, primary_key=True)
nursery_name = models.CharField(max_length=30)
序列化程序.py
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['email', 'username', 'contact', 'password']
extra_kwargs = {'password': {'write_only': True}}
class UserSerializer(serializers.ModelSerializer):
account = AccountSerializer(many=False)
class Meta:
model = User
fields = ['account', 'full_name', 'address']
def create(self, validated_data):
account_data = validated_data.pop('account')
user = User.objects.create(**validated_data)
Account.objects.create(user=user, **account_data)
return user
class NurserySerializer(serializers.ModelSerializer):
account = AccountSerializer(many=False)
class Meta:
model = Nursery
fields = ['account', 'nursery_name']
def create(self, validated_data):
account_data = validated_data.pop('account')
nursery = Nursery.objects.create(**validated_data)
Account.objects.create(nursery=nursery, **account_data)
return nursery
class UserLoginSerializer(serializers.Serializer):
email = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
account = authenticate(**data)
if account and account.is_active:
return account
raise serializers.ValidationError("Incorrect Credentials")
class NurseryLoginSerializer(serializers.Serializer):
email = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
account = authenticate(**data)
if account and account.is_active:
return account
raise serializers.ValidationError("Incorrect Credentials")
views.py
from rest_framework import generics, permissions
from rest_framework.response import Response
from .serliaziers import UserSerializer, NurserySerializer, UserLoginSerializer, NurseryLoginSerializer, AccountSerializer
class RegisterUserAPI(generics.GenericAPIView):
serializer_class = UserSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
})
class RegisterNurseryAPI(generics.GenericAPIView):
serializer_class = NurserySerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
nursery = serializer.save()
return Response({
"nursery": NurserySerializer(nursery, context=self.get_serializer_context()).data,
})
class LoginUserAPI(generics.GenericAPIView):
serializer_class = UserLoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
account = serializer.validated_data
return Response({
"user": UserSerializer(account, context=self.get_serializer_context()).data,
})
class LoginNurseryAPI(generics.GenericAPIView):
serializer_class = NurseryLoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
nursery = serializer.validated_data
return Response({
"user": NurserySerializer(nursery, context=self.get_serializer_context()).data,
})
url.py
from django.urls import path, include
from .api import RegisterUserAPI, RegisterNurseryAPI, LoginNurseryAPI, LoginUserAPI
urlpatterns = [
path('api/auth/register/user', RegisterUserAPI.as_view()),
path('api/auth/register/nursery', RegisterNurseryAPI.as_view()),
path('api/auth/login/nursery', LoginNurseryAPI.as_view()),
path('api/auth/login/user', LoginUserAPI.as_view())
]
试试这样的
UserLoginView继承自GetainAuthToken,它在项目中查找AUTH_USER_模型,并根据您在其中指定的用户模型请求所需参数以登录该用户
我希望这有帮助
编辑
要在注册用户时获取令牌,可以执行以下操作:
在您向api发出请求并成功响应之后,您向登录端点发出另一个请求
相关问题 更多 >
编程相关推荐