Метод обновления вложенного сериализатора в структуре Django Rest для полей M2M - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть три модели в моем 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"],
    }

Поскольку у меня естьМ2М через таблицу. Моя стратегия создания новой группы 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-адресе. Псевдокод выглядит следующим образом:

  1. Вывести список служб.
  2. Сохранить имя в идентификаторе экземпляра.
  3. Найдите существующие службы, связанные с ServiceGroup.
  4. Для служб, общих в существующем списке и списке полезной нагрузки JSON, ничего не делайте.
  5. Для служб в существующем списке ине в полезной нагрузке, удалите ассоциации M2M.
  6. Для служб, которых нет в существующем списке и в полезной нагрузке, создайте ассоциации 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>]>

Итак, я попробовал выше, и это не сработало.

1 Ответ

0 голосов
/ 10 декабря 2018

вы можете переопределить метод обновления

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...