如何在ManyToManyField上进行部分更新?我还需要验证它。 Django休息

时间:2018-04-03 01:24:32

标签: django django-rest-framework

我希望能够通过GET请求部分更新实例。

urls.py

urlpatterns=[
    url(r'^classes/(?P<pk>\d+)/add_student/(?P<student_id>\d+)', views.add_student),
]

models.py

class Class(models.Model):
    students = models.ManyToManyField('Student', related_name='classes')
    max_capacity = models.PositiveIntegerField()
    ...

class Student(models.Model):
    ...

以下不起作用,但我想要的是能够部分更新class_实例。我想将一个学生添加到此Class实例中。 此外,我希望我的序列化程序中的验证代码拒绝更新,如果它不好。

views.py

def add_student(request, pk, student_id):
    class_ = get_object_or_404(Class, id=pk)
    student = get_object_or_404(Student, id=student_id)
    class_.students.add(student)
    serializer = ClassSerializer(
        class_, 
        data={'students': class_.students}, 
        partial=True
            )
    if serializer.is_valid(raise_exception=True):
        serializer.save()
    return redirect('class-detail', pk=pk)

serializer.py

class ClassSerializer(serializers.ModelSerializer):
    ...
    def validate(self, data):
        students = data['students']
        max_capacity = data['max_capacity']
        if len(students) > max_capacity:
            msg = 'This class is full'
            raise serializers.ValidationError(msg)
        return data

请帮助,我真的不知道该怎么办。我不知道在哪里放置我的代码。我会接受任何修改或替换代码

1 个答案:

答案 0 :(得分:0)

好的,现在你的问题比以前的问题要清楚得多,尝试这样的事情来完成你的需要:

from django.conf import settings
from rest_framework.serializers import ModelSerializer, IntegerField
from students.fields import StudentRelatedField


class ClassSerializer(ModelSerializer):
    id = IntegerField(read_only=True)
    student = StudentRelatedField(
        queryset=Student.objects.all(), many=True, required=True
    )

    def update(self, instance, validated_data):
        # We are looking here if someone wants to add students to particular class:
        if 'student' in validated_data:
            # For each of that students:
            # Also note that validated_data['student'] is a List of Objects
            for i in validated_data['student']:
                # If each of that students ARE NOT in our particular Class already:
                if i not in instance.student.all():
                    # And if our particular Class IS NOT FULL ALREADY:
                    if instance.student.count() < settings.MAX_CAPACITY:
                        # Then we will add that student to our particular Class!
                        instance.student.add(i)
                    # Otherwise we will raise an Error!
                    else:
                        raise serializers.ValidationError('This Class Is Full!')

同时将其添加到您的settings.py文件中:

MAX_CAPACITY = 40

您的students -> fields.py文件应如下所示:

from rest_framework.serializers import RelatedField

class StudentRelatedField(RelatedField):

    def to_representation(self, obj):
        data = {
            'id': obj.id,
            'name': obj.name
        }
        return data

    def to_internal_value(self, pk):
        return Student.objects.get(id=pk)