禁止直接分配到相关集的反面。改为使用addresses.set()

Posted

技术标签:

【中文标题】禁止直接分配到相关集的反面。改为使用addresses.set()【英文标题】:Direct assignment to the reverse side of a related set is prohibited. Use addresses.set() instead 【发布时间】:2019-12-15 19:36:48 【问题描述】:

我将创建和更新嵌套关系,但它没有按预期工作我有三个模型用户、配置文件和地址。 Profile 模型是 Address 模型中的 FK

profiles/models.py

class Address(models.Model):
   profile = models.ForeignKey(Profile, related_name='addresses', on_delete=models.CASCADE)
   country = models.CharField(max_length=255)
   city = models.CharField(max_length=255)
   state = models.CharField(max_length=100)
   zip_code = models.CharField(max_length=50)
   address = models.CharField(max_length=1000)

profiels/serializers.py

class ProfileSerializer(serializers.ModelSerializer):
    addresses = AddressSerializer(many=True)

class Meta:
    model = Profile
    fields = ['gender', 'date_of_birth', 'hometown', 'phone', 'addresses']

def create(self, validated_data):
    addresses_data = validated_data.pop('addresses')
    profile = Profile.objects.create(**validated_data)
    for address_data in addresses_data:
        Address.objects.create(profile=profile, **address_data)
    return profile

users/serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):
profile = ProfileSerializer(required=True)
class Meta:
    model = User
    fields = ['id', 'url', 'first_name', 'last_name', 'email', 'password', 'profile']
    extra_kwargs = 'password': 'write_only': True

def create(self, validated_data):
    profile_data = validated_data.pop('profile')
    password = validated_data.pop('password')
    user = User(**validated_data)
    user.set_password(password)
    user.save()
    Profile.objects.create(user=user, **profile_data)
    return user

def update(self, instance, validated_data):
    profile_data = validated_data.pop('profile')
    profile = instance.profile
    instance.email = validated_data.get('email', instance.email)
    instance.first_name = validated_data.get('first_name', instance.first_name)
    instance.last_name = validated_data.get('last_name', instance.last_name)
    instance.save()

    profile.gender = profile_data.get('gender', profile.gender)
    profile.date_of_birth = profile_data.get('date_of_birth', profile.date_of_birth)
    profile.hometown = profile_data.get('hometown', profile.hometown)
    profile.phone = profile_data.get('phone', profile.phone)
    profile.addresses = profile_data.get('addresses', profile.addresses)
    profile.save()

它与我可以创建和更新的用户和个人资料配合得很好,但是当我添加 地址 时,它会给我上面标题中显示的错误。我还不知道如何解决嵌套关系。任何帮助将不胜感激)在此先感谢!

【问题讨论】:

【参考方案1】:

你的问题在于这一行

profile.addresses = profile_data.get('addresses', profile.addresses)

正如错误消息所示,不允许直接分配给关系的反面。你想要做的是使用 set() 代替。

profile.addresses.set([list of new addresses])

https://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager.set

【讨论】:

@jmp 感谢您的回答,但我不知道该写什么。你能告诉我吗?如果我写地址模型的实例,它说地址模型得到了“国家”属性

以上是关于禁止直接分配到相关集的反面。改为使用addresses.set()的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:禁止直接分配到多对多集合的前向端。请改用 meeting.set()。 Django m2m 字段出错

如何将结果集的多个值获取到 Java 对象中

Unity之Addressable使用注意事项

IfcPreDefinedPropertySet

IfcPreDefinedPropertySet

如何将NSString直接分配给NSMutableData?