我的models.py中有三个模型,如下所示:

class Service(models.Model):
     name = models.CharField(max_length=50, unique=True)
     port = models.PositiveSmallIntegerField()
     protocol = models.CharField(max_length=50)

class ServiceGroup(models.Model):
     name = models.CharField(max_length=50, unique=True)
     services = models.ManyToManyField(Service, through=ServiceToServiceGroup)

class ServiceToServiceGroup(models.Model):
    service = models.ForeignKey(Service)
    service_group = models.ForeignKey(ServiceGroup)


用于创建新服务组的JSON有效负载如下:

    {
    "name": "test_service_group1",
    "services":["service_1", "service_2"],
    }


由于我有一个M2M直通表,因此我创建新ServiceGroup的策略是首先弹出服务列表,使用名称创建ServiceGroup,然后创建M2M代理。

我创建新ServiceGroup的序列化器如下:

class ServiceGroupCreateUpdateSerializer(serializers.ModelSerializer):
    services = serializers.SlugRelatedField(queryset=Service.objects.all(),
                                            slug_field='name', many=True)
    class Meta:
        model = ServiceGroup
        fields = ['id', 'name', 'services']

    def create(self, validated_data):
        # Pop the services list out
        services = validated_data.pop('services', None)
        # Create the ServiceGroup with the name
        service_group = ServiceGroup.objects.create(name=validated_data['name'])
        #Create M2M associations
        for service in services:
            service_id = Service.objects.get(name=service)
            ServiceToServiceGroup.objects.create(service_id=service_id,
                                                 service_group_id= service_group.id)


我的问题是现在该如何编写更新方法?我的JSON有效负载保持不变,唯一的区别是我在URL中传递了实例ID。伪代码如下:


弹出服务列表。
将名称保存到实例ID。
查找链接到ServiceGroup的现有服务。
对于现有列表和JSON有效负载列表中的公共服务,什么都不做。
对于现有列表中而不是有效负载中的服务,请删除M2M关联。
对于不在现有列表和有效负载中的服务,请创建M2M关联。


对于更新方法而言,这似乎需要大量工作。有更简单的方法吗?

更新

In [145]: instance = ServiceGroup.objects.get(pk=1)

In [146]: instance.services.all()
Out[146]: <QuerySet [<Service: test-create442>]>

In [147]: new_services_list = ['test-create398']

In [148]: service_objects =
Service.objects.filter(name__in=new_services_list).all()

In [149]: service_objects
Out[149]: <QuerySet [<Service: test-create398>]>

In [150]: instance.service_set = service_objects

In [151]: instance.save()

In [152]: instance.services.all()
Out[152]: <QuerySet [<Service: test-create442>]>


因此,我尝试了上述操作,但没有成功。

最佳答案

您可以覆盖更新方法

def update(self, instance, validated_data):
    # Pop the services list out
    services = validated_data.pop('services', None)
    instance = super().update(instance, validated_data)
    service_objects = Service.objects.filter(name__in=services).all()
    ServiceToServiceGroup.objects.filter(service_group=instance).delete()
    service_group_obj = []
    for service in service_objects:
        service_group_obj(ServiceToServiceGroup(service=service, service_group=instance))
    ServiceToServiceGroup.objects.bulk_create(service_group_obj)
    return instance

关于python - Django Rest框架嵌套序列化程序的M2M字段更新方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53703734/

10-09 03:07