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

时间:2014-12-05 10:12:18

标签: 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',
        )

models.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)

views.py

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

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

2 个答案:

答案 0 :(得分:4)

我假设您使用的是新版本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.')
[...]

如果您需要更高级的验证,例如要验证两个相关字段,则需要覆盖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.')
[...]

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

的方法

link上方和www.django-rest-framework.org/api-guide/serializers/#validation中有更多提示。

答案 1 :(得分:3)

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

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)