Python 使用Django中的嵌套序列化程序创建2个相关模型的实例
我是Django的新手,我的代码遇到了这个问题。 我有一个自定义用户模型和一个帐户模型,它们由多对多字段关联 在注册过程中,要求用户创建或不创建帐户(通过链接加入其他帐户)Python 使用Django中的嵌套序列化程序创建2个相关模型的实例,python,django,django-rest-framework,many-to-many,Python,Django,Django Rest Framework,Many To Many,我是Django的新手,我的代码遇到了这个问题。 我有一个自定义用户模型和一个帐户模型,它们由多对多字段关联 在注册过程中,要求用户创建或不创建帐户(通过链接加入其他帐户) 如果用户创建了一个帐户,则他是该帐户的所有者,其他用户可以加入该帐户。(未完成所有权代码) 一个用户可以同时是多个帐户的一部分 在注册视图中创建(或不创建)帐户和用户 我在文档中读到了关于嵌套序列化程序的内容,我认为这应该创建两个模型实例。 如何使用嵌套序列化程序在一个视图中创建关系? 其他解决问题的方法 型号 clas
- 如果用户创建了一个帐户,则他是该帐户的所有者,其他用户可以加入该帐户。(
)未完成所有权代码
- 一个用户可以同时是多个帐户的一部分
- 在注册视图中创建(或不创建)帐户和用户
class Account(models.Model):
AccountName = models.TextField(max_length=100, blank=False, null=False)
class AccountCreationSerializer(ModelSerializer):
class Meta:
model = Account
fields = ['AccountName']
序列化程序
class Account(models.Model):
AccountName = models.TextField(max_length=100, blank=False, null=False)
class AccountCreationSerializer(ModelSerializer):
class Meta:
model = Account
fields = ['AccountName']
查看
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: ****
错误:
禁止直接分配到多对多集合的前端。改为使用AccountName.set()代码>
在自定义模型中创建用户
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
我很确定我在很多领域都犯了一些错误,但还没有找到解决方案。任何帮助都会对我有益。蒂亚 您不能将值直接保存到多对多
字段。数据库不允许您这样做。它仅允许您添加它们以关联两个表之间的关系(即User
,Account
)。将序列化程序
文件的代码段替换为以下代码段
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 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\u user
方法有问题。您在这里传递的是多对多
字段引用(AccountName),您不应该这样做。正如我前面提到的,您不能直接保存多对多
字段。你只需要把它们之间的关系联系起来。忽略这一点,它将工作
遵循此方法的新定义(create\u user
)
我添加了代码,但它的行为仍然相同。我需要动态添加Account和User的实例,并在同一运行时关联它们的关系,我认为这不会将它们绑定在一起。我正在创建一个超级用户,在提供Account和CreateCount=True的详细信息后,仍然会出现相同的错误。@otaku_weeb,我已经编辑了答案。检查一下。希望这一次能对你有所帮助。它仍然会抛出同样的错误直接赋值到多对多集合的前端是被禁止的。改用AccountName.set()。
@otaku\u weeb,我不这么认为。也许您没有完全按照我在这里所说的那样遵循源代码。在我的源代码中,由于我已经正确地处理了与多对多
字段相关的情况,所以前面的错误不应该再次出现。我在这里给出的解决方案已经使用我的机器进行了正确的测试。API工作正常。如果您觉得仍然没有达到预期效果,那么您需要更新这些方法(post
,create\u user
)和模型管理器(MyAccountManager
)的问题。@otaku\u weeb,请检查我答案的更新部分。
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