Обновление массива поля ManyToMany во фреймворке Django REST

У меня есть модель Plot, которая выглядит следующим образом:

from django.db import models


class Plot(models.Model):
    class SUNSHINE(models.TextChoices):
        NONE = None
        FULL_SUN = 'Plein soleil',
        SHADOW = "Dans l'ombre",
        SUNNY = 'Ensoleillée',
        MODERATE = 'Modérée'

    name = models.CharField(max_length=50)
    garden = models.ForeignKey('perma_gardens.Garden', on_delete=models.CASCADE)
    width = models.CharField(max_length=50, blank=True, null=True)
    height = models.CharField(max_length=50, blank=True, null=True)

    exposition = models.CharField(max_length=50, choices=SUNSHINE.choices, default=SUNSHINE.NONE, blank=True,
                                  null=True)

    qr_code = models.CharField(max_length=50, blank=True, null=True)

    plant = models.ManyToManyField('perma_plants.Plant', related_name='%(class)s_plant', blank=True)

    def __str__(self):
        return self.name

With a plant object that is a foreign key of the model of the same name. И у меня есть эта partial_update функция в моем представлении:

class PlotViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    queryset = Plot.objects.all()

    def partial_update(self, request, *args, **kwargs):
        instance = self.queryset.get(pk=kwargs.get('pk'))
        serializer = WritePlotSerializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

Но когда, в моем фронте, я хочу обновить растения на моем участке, я могу выбрать несколько из них, и когда я нажимаю на кнопку добавить, он работает, он обновляется, но он удаляет старые растения, присутствующие или я хотел бы, чтобы, когда я обновляю, он сохраняет растения, которые уже присутствовали в массиве, затем он добавляет тот, который мы только что добавили. Как я могу сделать, чтобы получить такой результат?

Вот мой сериализатор модели Plot :

from rest_framework import serializers
from .models import Plot
from apps.perma_plants.models import Plant
from apps.perma_gardens.models import Garden
from apps.perma_plant_categories.models import PlantCategory


class GardenSerializer(serializers.ModelSerializer):

    class Meta:
        model = Garden
        fields = ('id', 'name',)

class PlantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Plant
        fields = ('id', 'name', "category", 'image', 'facility_rate', 'sunshine_index', 'irrigation_index')

class ReadPlotSerializer(serializers.ModelSerializer):
    garden = GardenSerializer(required=True)
    plant = PlantSerializer(many=True)
    id = serializers.IntegerField(read_only=True)

    class Meta:
        model = Plot
        fields = '__all__'
        read_only_fields = [fields]

class WritePlotSerializer(serializers.ModelSerializer):

    class Meta:
        model = Plot
        fields = '__all__'

Спасибо за ваш отзыв!

Есть несколько способов решить эту проблему:

1- отправить весь массив в запросе

2- добавьте логику в сериализатор, используя какой-либо валидатор. Обратитесь к https://stackoverflow.com/a/66293267/9459826

3- добавьте смысл в сериализатор, используя SerializerMethodField, как

plants = serializers.SerializerMethodField()
def get_plants(self, obj):
    fetched_plants = fetch_plants()
    return plants

Что лучше - зависит от вас, хотите ли вы исправить это на этапе валидации или нет.

Вот документация: https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

https://www.django-rest-framework.org/api-guide/serializers/#validation

Вернуться на верх