如何从Django Rest Framework neasted serializer的ManyToMany Field中删除对象?

问题描述 投票:0回答:1

我可以成功地将一个新的对象添加到 notification_days 但什么是处理删除任何对象的最习惯的方式?

模型.py

DAYS_OF_WEEK = (
    (0, 'Mon'),
    (1, 'Tue'),
    (2, 'Wed'),
    (3, 'Thu'),
    (4, 'Fri'),
    (5, 'Sat'),
    (6, 'Sun'),
)

class WeekDay(models.Model):
    day = models.IntegerField(choices=DAYS_OF_WEEK)

    def __str__(self):
        return self.get_day_display()


class Company(models.Model):
    name = models.CharField(...)
    notification_days = models.ManyToManyField(WeekDay)

serializers.py

class WeekDaySerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    day_display = serializers.SerializerMethodField()

    class Meta:
        model = WeekDay
        fields = ['id', 'day', 'day_display']

    def get_day_display(self, obj):
        return obj.get_day_display()

class CompanySettingsSerializer(serializers.ModelSerializer):
    notification_days = WeekDaySerializer(many=True)

    class Meta:
        model = Company
        fields = [
            'name',
            'notification_days'

        ]

    def update(self, instance, validated_data):
        notification_days = validated_data.get('notification_days')

        for day in notification_days:
            day_id = day.get('id', None)

            if item_id:
                if not instance.notification_days.filter(pk=day_id).exists():
                    week_day = WeekDay.objects.get(pk=day_id)
                    instance.notification_days.add(week_day)

        return instance

api.py

class CompanySettingsAPIView(RetrieveUpdateAPIView):
    authentication_classes = (SessionAuthentication, )
    permission_classes = (IsCompanyAdmin, )
    serializer_class = CompanySettingsSerializer

    def get_object(self):
        return Company.objects.get(pk=self.kwargs.get('pk'))

GET响应示例。

{
    "name": "Django",
    "notification_days": [
        {
            "id": 1,
            "day": 0,
            "day_display": "Mon"
        },
        {
            "id": 2,
            "day": 1,
            "day_display": "Tue"
        }
    ]
}

当我发送PUT请求时,成功地添加了新的星期日。

{
    "name": "Django",
    "notification_days": [
        {
            "id": 1,
            "day": 0,
            "day_display": "Mon"
        },
        {
            "id": 2,
            "day": 1,
            "day_display": "Tue"
        },
        {
            "id": 4,
            "day": 3
        }
    ]
}
django django-rest-framework
1个回答
1
投票

你只需要请求中的id.并且使用 .set() 方法来更新关系。

PUT请求。

{
  "name": "Django",
  "notification_days_ids": [
    1,
    2,
    4
  ]
}

Serializer:

class CompanySettingsSerializer(serializers.ModelSerializer):
    notification_days = WeekDaySerializer(many=True, read_only=True)
    notification_days_ids = serializers.PrimaryKeyRelatedField(
        many=True,
        write_only=True,
        source='notification_days',  # just to make it looks a little bit better
        queryset=WeekDay.objects.all()
    )

    class Meta:
        model = Company
        fields = [
            'name',
            'notification_days',
            'notification_days_ids',
        ]

    def update(self, instance, validated_data):
        if 'notification_days' in validated_data:  # to handle PATCH request
            instance.notification_days.set(validated_data['notification_days'])

        return instance
© www.soinside.com 2019 - 2024. All rights reserved.