我希望能够通过GET请求来更新实例。
URLs.朋友
urlpatterns=[
url(
r'^classes/(?P<pk>\d+)/add_student/(?P<student_id>\d+)',
views.add_student
),
]
views.朋友
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.朋友
class Class(models.Model):
students = models.ManyToManyField('Student', related_name='classes')
...
class Student(models.Model):
...
serialize人.朋友
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)
这将学生成功地添加到类,即使类是满的。如何更新这个样子,和学生被添加之前将其交由串行验证?
尝试这个:
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
UPDATE
根据您的更新和你views.py
,您可以检查计数,而在validate()
使用vserializer
。
更改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)
http://www.django-rest-framework.org/api-guide/serializers/#validation
串行validate()方法获得只有当你调用序列化对象is_valid()方法调用。
改变你的方法是这样
def add_student(request, pk, student_id):
class_ = get_object_or_404(Class, id=pk)
serializer = ClassSerializer(data=class_)
if serializer.is_valid(): # add student
student = get_object_or_404(Student, id=student_id)
class_.students.add(student)
return redirect('class-detail', pk=pk)
else:
errors = serializer.errors
# handle errors