Django Rest Framework - 在保存到数据库之前检查/操作数据(通过某种逻辑)

Iqb*_*bal 5 django-rest-framework

我是 Django Rest Framework 的新手。我有一个这样的序列化程序:

class ReviewSerializer(serializers.ModelSerializer):
    class Meta:
        model = Review
        fields = (
            'user',
            'course',
            'major',
            'title',
            'text',
            'placements',
            'faculty',
            'infrastructure',
            'students',
            'extra_curricular',
            'passing_year',
        )
Run Code Online (Sandbox Code Playgroud)

模型.py

class Review(models.Model):
    user = models.ForeignKey(to=User, related_name='reviews')
    course = models.ForeignKey(to=Course, related_name='reviews')
    major = models.ForeignKey(to=Major, related_name='reviews', blank=True, null=True)
    title = models.TextField(db_index=True)
    text = models.TextField(db_index=True)
    placements = models.FloatField(default=0.0)
    faculty = models.FloatField(default=0.0)
    infrastructure = models.FloatField(default=0.0)
    students = models.FloatField(default=0.0)
    extra_curricular = models.FloatField(default=0.0)
    passing_year = models.PositiveSmallIntegerField(default=2014)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)

views.py

class ReviewViewSet(viewsets.ModelViewSet):
    """
    College API
    """
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer
    paginate_by = 5
Run Code Online (Sandbox Code Playgroud)

现在,每当我向 API 发布内容时,如果验证成功通过,它就会直接保存到数据库中。我需要的是,在将数据保存到数据库之前,我想使用一些业务逻辑检查并应用一些数据条件。因此,如果条件为真,则数据才会被保存,否则它会向客户端返回错误消息。

use*_*459 5

我假设您使用的是新版本 3.0。然后,您需要将验证逻辑放入序列化程序中ReviewSerializer(请参阅http://www.django-rest-framework.org/topics/3.0-announcement/#serializers)。

因此,如果您想创建字段验证,您应该重载def validate_<fieldname>(self, value). 例如,如果你想Review.placements成为>= 0.0,你可以写

class ReviewSerializer(serializers.ModelSerializer):
[...]
    def validate_placements(self, value):
         if value >= 0.0:
              return value
         raise serializers.ValidationError('placements should be non-negative.')
[...]
Run Code Online (Sandbox Code Playgroud)

如果您需要更高级的验证,例如验证两个依赖字段,那么您需要覆盖def validate(self, attrs).

例如有 created_on <= updated_on

class ReviewSerializer(serializers.ModelSerializer):
[...]
    def validate(self, attrs):
        if attrs['created_on'] <= attrs['update_on']:
            return attrs
        raise ValidationError('Date of creation should be before update date.')
[...]
Run Code Online (Sandbox Code Playgroud)

如果您现在通过 REST-API 添加一些对象,将自动调用验证。您不必覆盖ModelViewSet.

在上面的链接www.django-rest-framework.org/api-guide/serializers/#validation 中有更多提示。


Mat*_*tko 3

您可以重写 ModelViewSet 内的默认创建方法。当您向 API 发布(POST http 方法)某些内容时,会调用此方法。然后您可以检查序列化数据是否有效,然后在保存它们之前应用您的业务逻辑:

class ReviewViewSet(viewsets.ModelViewSet):
    """
    College API
    """
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer
    paginate_by = 5

    def create(self, request):
        serializer = ReviewSerializer(data=request.DATA)
        if serializer.is_valid():

            #YOUR CODE HERE

            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)