【问题标题】:Django Rest Framework - Override serializer create method for model with self-referential M2M fieldDjango Rest Framework - 为具有自引用 M2M 字段的模型覆盖序列化程序创建方法
【发布时间】:2017-10-18 20:09:00
【问题描述】:

我有一个看起来像这样的模型:

class Profile(models.Model):
    following = models.ManyToManyField('Profile', related_name='followed')
    admin_notes = models.TextField()

还有一个看起来像这样的 Django Rest Framework 序列化程序:

class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Profile
        fields = '__all__'

创建新的Profile 时,我想中断保存/创建以编程方式设置admin_notes。我知道如何在基于函数的视图中执行此操作,但这次我使用的是 DRF 的视图集,因此我想在序列化程序中执行此操作。不过,自我参照关系给我带来了麻烦。

我在ProfileSerializer: 中试过这个:

def create(self, **validated_data):
    p = Profile(**validated_data)
    p.admin_notes = 'Test'
    p.save()

这以及尝试Profile.objects.create 而不是仅仅在第一行创建一个新的Profile 实例,导致以下错误:

Exception Value: "<Profile>" needs to have a value for field "id" before this many-to-many relationship can be used.

试试这个:

def create(self, validated_data):
    validated_data['admin_notes'] = 'Test'
    return super(ProfileSerializer, self).create(**validated_data)

导致此错误:

Exception Value: create() got an unexpected keyword argument 'following'

我知道 Django 在两步保存过程中创建 m2m 关系,所以这个错误是有道理的,但仍然让我对如何继续前进感到困惑。鉴于我的模型设置方式,如何在序列化程序中设置 admin_notes 的值?

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    试试这个(假设您将 Profile 实例的 id 传递给您的 m2m 字段):

    def create(self, validated_data):
    
        # First, remove following from the validated_data dict...
        following_data = validated_data.pop('following', None)
    
        # Set the admin_notes custom value...
        validated_data['admin_notes'] = 'Test'
    
        # Create the object instance...
        profile = Profile.objects.create(**validated_data)
    
        # Finally, add your many-to-many relationships...
        if following_data:
            for data in following_data:
                profile.followed.add(Profile.objects.get(**data))
        return profile
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 2018-10-18
      • 1970-01-01
      相关资源
      最近更新 更多