Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Django中的嵌套序列化程序创建2个相关模型的实例_Python_Django_Django Rest Framework_Many To Many - Fatal编程技术网

Python 使用Django中的嵌套序列化程序创建2个相关模型的实例

Python 使用Django中的嵌套序列化程序创建2个相关模型的实例,python,django,django-rest-framework,many-to-many,Python,Django,Django Rest Framework,Many To Many,我是Django的新手,我的代码遇到了这个问题。 我有一个自定义用户模型和一个帐户模型,它们由多对多字段关联 在注册过程中,要求用户创建或不创建帐户(通过链接加入其他帐户) 如果用户创建了一个帐户,则他是该帐户的所有者,其他用户可以加入该帐户。(未完成所有权代码) 一个用户可以同时是多个帐户的一部分 在注册视图中创建(或不创建)帐户和用户 我在文档中读到了关于嵌套序列化程序的内容,我认为这应该创建两个模型实例。 如何使用嵌套序列化程序在一个视图中创建关系? 其他解决问题的方法 型号 clas

我是Django的新手,我的代码遇到了这个问题。 我有一个自定义用户模型和一个帐户模型,它们由多对多字段关联

在注册过程中,要求用户创建或不创建帐户(通过链接加入其他帐户)

  • 如果用户创建了一个帐户,则他是该帐户的所有者,其他用户可以加入该帐户。(
    未完成所有权代码
  • 一个用户可以同时是多个帐户的一部分
  • 在注册视图中创建(或不创建)帐户和用户
我在文档中读到了关于嵌套序列化程序的内容,我认为这应该创建两个模型实例。 如何使用嵌套序列化程序在一个视图中创建关系? 其他解决问题的方法

型号

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