在 Django 中使用嵌套序列化程序创建 2 个相关模型的实例
Creating instances of 2 related models using nested serializer in Django
我是 Django 的新手,我在我的代码中遇到过这个问题。
我有一个自定义用户模型和一个帐户模型,它们由多对多字段关联。
在注册过程中,系统会要求用户创建或不创建帐户(通过 link 加入其他帐户)。
- 如果用户创建了一个帐户,那么他就是该帐户的所有者,其他用户可以加入该帐户。(
Did not finish the code for ownership
)
- 一个用户可以同时是多个帐户的一部分。
- 在注册视图中创建(或不创建)帐户和用户。
我在文档中阅读了有关嵌套序列化程序的信息,我认为这应该创建两个模型实例。
如何使用嵌套序列化程序在一个视图中创建关系?
解决问题的其他方法?
型号
class Account(models.Model):
AccountName = models.TextField(max_length=100, blank=False, null=False)
class User(AbstractBaseUser):
AccountName = models.ManyToManyField(Account)
CreateAccount = models.BooleanField(blank=False, null=False)
EmailId = models.EmailField(max_length=128, blank=False, null=False, unique=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'EmailId'
REQUIRED_FIELDS = ['AccountName', 'CreateAccount',]
# Implemented the other req. functions
objects = MyAccountManager()
序列化程序
class AccountCreationSerializer(ModelSerializer):
class Meta:
model = Account
fields = ['AccountName']
class SignUpSerializer(ModelSerializer):
AccountName = AccountCreationSerializer()
class Meta:
model = User
fields = ['EmailId', 'AccountName', 'CreateAccount', 'password']
extra_kwargs = {'password': {'write_only': True, 'required': True}}
def create(self, validated_data):
AccountName = validated_data.pop('AccountName')
if validated_data['CreateAccount']: #Create only when this is True
Account.objects.create(AccountName=AccountName, **AccountName)
userAcc = User.objects.create_user(**validated_data)
return userAcc
查看
class SignUpView(APIView):
def post(request):
# to edit
signup_serializer = SignUpSerializer(data=request.data)
# rest of the view
要求
// 忽略引号
EmailID: xyz@gmail.com
AccountName: TestAcc
CreateAccount: False
Password: ****
错误:
Direct assignment to the forward side of a many-to-many set is prohibited. Use AccountName.set() instead.
Create_user 自定义模型
def create_user(self, EmailId, AccountName, CreateAccount, password):
if not EmailId:
raise ValueError("Users must have an email")
user = self.model(
EmailId=self.normalize_email(EmailId),
AccountName=AccountName,
CreateAccount=CreateAccount,
)
user.set_password(password)
user.save(using=self._db)
return user
我很确定我在 manytomany 领域犯了一些错误,但一直无法找出解决方案。任何帮助都会对我有益。 TIA!
您不能将值直接保存到 many-to-many
字段。数据库不允许你这样做。它只允许您添加它们以关联两个表之间的关系( i.e User
, Account
)。将 Serializer
文件的代码段替换为以下代码段。
class AccountCreationSerializer(ModelSerializer):
class Meta:
model = Account
fields = ['AccountName']
class SignUpSerializer(ModelSerializer):
AccountName = serializers.SerializerMethodField()
class Meta:
model = User
fields = ['EmailId', 'AccountName', 'CreateAccount', 'password']
extra_kwargs = {'password': {'write_only': True, 'required': True}}
def validate(self, attrs):
attrs = super(SignUpSerializer, self).validate(attrs=attrs)
attrs.update({"AccountName": self.initial_data.get("AccountName")})
return attrs
def create(self, validated_data):
AccountName = validated_data.pop('AccountName')
acc = Account.objects.create(AccountName=AccountName) if "CreateAccount" in validated_data and validated_data['CreateAccount'] else None
userAcc = User.objects.create_user(**validated_data)
if acc:
userAcc.AccountName.add(acc)
return userAcc
最后,将你的SignUpView
class替换成下面的方式:
class SignUpView(APIView):
serializer_class = SignUpSerializer
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
is_valid_serializer = serializer.is_valid(raise_exception=True)
if is_valid_serializer:
with transaction.atomic():
serializer.save()
# Rest of your code segments to finalize the response
更新
您的 create_user
方法有问题。您在这里传递了 many-to-many
字段引用 (AccountName),这是您不应该传递的。正如我前面提到的,您不能直接保存 many-to-many
字段。你只需要关联它们之间的关系。忽略它,它将起作用!!!
遵循此方法的新定义 (create_user
)。
def create_user(self, EmailId, CreateAccount, password):
if not EmailId:
raise ValueError("Users must have an email")
user = self.model(EmailId=self.normalize_email(EmailId), CreateAccount=CreateAccount)
user.set_password(password)
user.save(using=self._db)
return user
我是 Django 的新手,我在我的代码中遇到过这个问题。 我有一个自定义用户模型和一个帐户模型,它们由多对多字段关联。
在注册过程中,系统会要求用户创建或不创建帐户(通过 link 加入其他帐户)。
- 如果用户创建了一个帐户,那么他就是该帐户的所有者,其他用户可以加入该帐户。(
Did not finish the code for ownership
) - 一个用户可以同时是多个帐户的一部分。
- 在注册视图中创建(或不创建)帐户和用户。
我在文档中阅读了有关嵌套序列化程序的信息,我认为这应该创建两个模型实例。 如何使用嵌套序列化程序在一个视图中创建关系? 解决问题的其他方法?
型号
class Account(models.Model):
AccountName = models.TextField(max_length=100, blank=False, null=False)
class User(AbstractBaseUser):
AccountName = models.ManyToManyField(Account)
CreateAccount = models.BooleanField(blank=False, null=False)
EmailId = models.EmailField(max_length=128, blank=False, null=False, unique=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'EmailId'
REQUIRED_FIELDS = ['AccountName', 'CreateAccount',]
# Implemented the other req. functions
objects = MyAccountManager()
序列化程序
class AccountCreationSerializer(ModelSerializer):
class Meta:
model = Account
fields = ['AccountName']
class SignUpSerializer(ModelSerializer):
AccountName = AccountCreationSerializer()
class Meta:
model = User
fields = ['EmailId', 'AccountName', 'CreateAccount', 'password']
extra_kwargs = {'password': {'write_only': True, 'required': True}}
def create(self, validated_data):
AccountName = validated_data.pop('AccountName')
if validated_data['CreateAccount']: #Create only when this is True
Account.objects.create(AccountName=AccountName, **AccountName)
userAcc = User.objects.create_user(**validated_data)
return userAcc
查看
class SignUpView(APIView):
def post(request):
# to edit
signup_serializer = SignUpSerializer(data=request.data)
# rest of the view
要求 // 忽略引号
EmailID: xyz@gmail.com
AccountName: TestAcc
CreateAccount: False
Password: ****
错误:
Direct assignment to the forward side of a many-to-many set is prohibited. Use AccountName.set() instead.
Create_user 自定义模型
def create_user(self, EmailId, AccountName, CreateAccount, password):
if not EmailId:
raise ValueError("Users must have an email")
user = self.model(
EmailId=self.normalize_email(EmailId),
AccountName=AccountName,
CreateAccount=CreateAccount,
)
user.set_password(password)
user.save(using=self._db)
return user
我很确定我在 manytomany 领域犯了一些错误,但一直无法找出解决方案。任何帮助都会对我有益。 TIA!
您不能将值直接保存到 many-to-many
字段。数据库不允许你这样做。它只允许您添加它们以关联两个表之间的关系( i.e User
, Account
)。将 Serializer
文件的代码段替换为以下代码段。
class AccountCreationSerializer(ModelSerializer):
class Meta:
model = Account
fields = ['AccountName']
class SignUpSerializer(ModelSerializer):
AccountName = serializers.SerializerMethodField()
class Meta:
model = User
fields = ['EmailId', 'AccountName', 'CreateAccount', 'password']
extra_kwargs = {'password': {'write_only': True, 'required': True}}
def validate(self, attrs):
attrs = super(SignUpSerializer, self).validate(attrs=attrs)
attrs.update({"AccountName": self.initial_data.get("AccountName")})
return attrs
def create(self, validated_data):
AccountName = validated_data.pop('AccountName')
acc = Account.objects.create(AccountName=AccountName) if "CreateAccount" in validated_data and validated_data['CreateAccount'] else None
userAcc = User.objects.create_user(**validated_data)
if acc:
userAcc.AccountName.add(acc)
return userAcc
最后,将你的SignUpView
class替换成下面的方式:
class SignUpView(APIView):
serializer_class = SignUpSerializer
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
is_valid_serializer = serializer.is_valid(raise_exception=True)
if is_valid_serializer:
with transaction.atomic():
serializer.save()
# Rest of your code segments to finalize the response
更新
您的 create_user
方法有问题。您在这里传递了 many-to-many
字段引用 (AccountName),这是您不应该传递的。正如我前面提到的,您不能直接保存 many-to-many
字段。你只需要关联它们之间的关系。忽略它,它将起作用!!!
遵循此方法的新定义 (create_user
)。
def create_user(self, EmailId, CreateAccount, password):
if not EmailId:
raise ValueError("Users must have an email")
user = self.model(EmailId=self.normalize_email(EmailId), CreateAccount=CreateAccount)
user.set_password(password)
user.save(using=self._db)
return user