我正在尝试在 Django 中创建一个多用户身份验证系统,并使用 onetoone 字段和布尔值来创建配置文件。但是在创建序列化器时它会抛出错误“字段名称
email
对模型customer
无效。”
有人可以澄清我在这里做错了什么吗?
模型.py:
from django.db import models
from django.contrib.auth.models import User,AbstractBaseUser,BaseUserManager
# Create your models here.
class UserManager(BaseUserManager):
def create_user(self, email, password, **extra_fields):
if not email:
raise ValueError("The email must be set")
if not password:
raise ValueError("The password must be set")
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
class user(AbstractBaseUser):
is_customer = models.BooleanField(default=False)
is_restaurant = models.BooleanField(default=False)
email = models.EmailField(max_length=100,unique=True)
USERNAME_FIELD = 'email'
objects = UserManager
class customer(models.Model):
user = models.OneToOneField(user,on_delete=models.CASCADE)
firstname = models.CharField(max_length=80)
lastname = models.CharField(max_length=80)
class restaurant(models.Model):
user = models.OneToOneField(user,on_delete=models.CASCADE)
rest_name = models.CharField(max_length=80)
serializers.py:-
from rest_framework import serializers
from .models import *
class userserializer(serializers.ModelSerializer):
class Meta:
model = user
fields = '__all__'
class cust_serializer(serializers.ModelSerializer):
class Meta:
model = customer
user = userserializer(read_only=False)
email = serializers.StringRelatedField(read_only=False,source = 'user.email')
password = serializers.StringRelatedField(source = 'user.password')
fields = [
'id',
'email',
'password',
'firstname',
'lastname',
]
def create(self,validated_data):
user1 = user.objects.create(self,email=validated_data['email'],password=validated_data['password'])
user1.is_customer = True
user1.save()
instance = customer.objects.create(user=user1,firstname = validated_data['firstname'],lastname = ['lastname'])
return user1
class rest_serializer(serializers.ModelSerializer):
class Meta:
model = customer
fields = [
'id',
# 'email',
#'password',
'rest_name',
]
def create(self,validated_data):
user = super().save()
user.is_restaurant = True
user.save()
instance = customer.objects.create(user=user,rest_name=validated_data['rest_name'])
return instance
views.py:-
from django.shortcuts import render
from .models import customer,restaurant,user
from .serializers import cust_serializer,rest_serializer
from rest_framework import generics
from rest_framework.response import Response
# Create your views here.
class createcustomer(generics.CreateAPIView):
serializer_class = cust_serializer
queryset = user.objects.filter(is_customer = True).values()
def post(self,request,*args,**kwargs):
cust = cust_serializer(data=request.data)
if cust.is_valid(raise_exception=True):
cust.save()
return Response(cust.data)
尝试了不同的方法,如上面所示的 stringrelatedfield 但没有进展。 使用
fields = ('__all__')
我将用户作为帖子请求中的字段之一
问题是您正在尝试访问
email
中 user
模型的 cust_serializer
字段,而您的 customer
模型中未定义该字段。相反,您应该为 user
模型定义一个序列化程序,并将其作为嵌套序列化程序包含在您的 cust_serializer
中。这是一个如何修改序列化程序的示例:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = user
fields = ['id', 'email', 'password']
extra_kwargs = {'password': {'write_only': True}}
class CustSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = customer
fields = ['id', 'user', 'firstname', 'lastname']
def create(self, validated_data):
user_data = validated_data.pop('user')
user1 = user.objects.create_user(**user_data)
user1.is_customer = True
user1.save()
instance = customer.objects.create(user=user1, **validated_data)
return instance
在这个例子中,我们为
UserSerializer
模型定义了一个单独的user
,并将其作为嵌套序列化程序包含在CustSerializer
中。我们还修改了 create
方法来处理 user
和 customer
实例的创建。
您可以类似地修改您的
RestSerializer
以包含嵌套的UserSerializer
。