如何在基于函数的视图中使用序列化程序验证? Django Rest

时间:2018-04-02 14:09:43

标签: django django-rest-framework

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

urls.py

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

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)
    return redirect('class-detail', pk=pk)

models.py

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

class Student(models.Model):
    ...

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)

即使课程已满,也可以成功将学生添加到课程中。我如何像这样更新,并验证它 在学生加入之前由序列化器?

2 个答案:

答案 0 :(得分:1)

试试这个:

def add_student(request, pk, student_id):
    class_ = get_object_or_404(Class, id=pk)

    # Change is here
    serializer = ClassSerializer(data=class_)
    serializer.is_valid(True)
    serialized_class_data = serializer.data

    student = get_object_or_404(Student, id=student_id)
    class_.students.add(student)
    return redirect('class-detail', pk=pk)

如果您需要通过序列化程序进行验证,则需要使用关键字参数data传递要验证的数据/实例,并且应该调用.is_valid()方法。

有关详细信息,请参阅official DRF doc

<强>更新
根据您的更新和views.py,您无需在validate()中使用v serializer即可查看计数。

更改您的views.py,如下所示:

from django.db.models import Count


def add_student(request, pk, student_id):
    class_ = get_object_or_404(Class, id=pk)
    std_count = class_.students.aggregate(count=Count('id'))['count']
    if std_count > max_capacity:
        return HttpResponse("This class is full")
    student = get_object_or_404(Student, id=student_id)
    class_.students.add(student)
    return redirect('class-detail', pk=pk)

答案 1 :(得分:0)

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

只有在序列化程序对象上调用 is_valid()方法时才会调用

序列化程序 validate()方法。

像这样改变你的方法

RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ http://your-website.com/$1 [R,L]
RewriteRule ^(system|application|uploads|cgi-bin) - [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [PT,L]