在SlugRelatedField多对多关系中允许重复

时间:2018-09-05 09:13:34

标签: python django django-rest-framework

我这样设置了SlugRelatedField

items = serializers.SlugRelatedField(
    slug_field='name', many=True, queryset=Item.objects.all())

当前,我正在以以下形式向数据库发送请求:

{
    items: [
        "item1",
        "item1",
        "item2",
    ]
}

但是,如果我查询相同的对象,则会得到以下信息:

{
    items: [
        "item1",
        "item2",
    ]
}

如何制作它,以便DRF完全插入我发送的内容而不删除重复项。

1 个答案:

答案 0 :(得分:0)

我设法进行了三处更改来解决此问题。为了避免我公司的版权问题,下面的所有代码均已更改,如果打错了,抱歉。首先,我创建了一个自定义的多对多模型,该模型允许重复输入:

class FooBar(models.Model):
    foo = models.ForeignKey(
        Foo, on_delete=models.SET_NULL, null=True)
    bar = models.ForeignKey(
        Bar, on_delete=models.SET_NULL, null=True)

然后,我在Foo类的ManyToMany字段中添加了一个through参数以使用新模型:

class Foo(models.Model):
    items = models.ManyToManyField(Foo, through='FooBar')

但是,仅这样做会导致AttributeError: Cannot set values on a ManyToManyField which specifies an intermediary model. Use my_package.FooBar's Manager instead.,这是因为Django Rest Framework无法自动创建自定义的多对多模型。因此,我们需要实现几个自定义序列化方法来解决该问题:

def create(self, validated_data):
    instance = Foo()
    instance.x = validated_data['x']
    instance.y = validated_data['y']
    instance.save()
    for bar in validated_data['bars']:
        relation = FooBar(foo=instance, bar=bar)
        relation.save()
    return instance

def update(self, instance, validated_data):
    instance.table = validated_data.get('x', instance.x)
    instance.status = validated_data.get('y', instance.y)
    instance.save()
    if 'bars' in validated_data:
        FooBar.objects.filter(foo=instance).delete()
        for bar in validated_data.get('bars', []):
            relation = FooBar(foo=instance, bar=bar)
            relation.save()
    return instance