Django:如何在发布请求后将数据保存到数据库之前如何检查数据是否正确?

时间:2019-04-02 12:42:32

标签: python django api validation django-rest-framework

我希望能够通过将django rest api项目中的发布请求中的数据发送到我的函数来解析该请求,该函数将在将数字保存到数据库之前将该数字有效且错误的情况下返回true或false。向发出请求的客户端发送自定义错误请求消息。

有人告诉我可以覆盖create方法来执行此操作,但是我不确定该怎么做。

到目前为止,我的代码如下:

class Messages(models.Model):
    phone_number = models.CharField(max_length=256, default='')
    message_body = models.CharField(max_length=256, default='')
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.phone_number + ' ' + self.message_body + ' ' + self.created

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        # I assume this is where I would do the check before saving it but not sure how? example would be like:
        # if numberValid(self.phone_number):
        #    then save to the database
        # else:
        #    then send back a bad request?
        super(Messages, self).save(force_update=force_update)
        send_sms(self.phone_number, self.message_body)

    def delete(self, using=None, keep_parents=False):
        super(Messages, self).delete(using=using, keep_parents=keep_parents)

因此,基本上,只是想就如何解决此问题提供一些指导。甚至有用的链接将不胜感激。我确实看过stackoverflow,但没有成功,也许我不知道如何在搜索时说明问题。

4 个答案:

答案 0 :(得分:3)

您可以使用DRF串行器的validation。例如,创建一个序列化器,并添加一个命名为import re class MessagesSerializer(serializers.ModelSerializer): class Meta: model = Messages fields = "__all__" def validate_phone_number(self, value): rule = re.compile(r'(^[+0-9]{1,3})*([0-9]{10,11}$)') if not rule.search(value): raise serializers.ValidationError("Invalid Phone Number") return value 的验证方法。然后在其中添加验证码:

class SomeView(APIView):
    def post(self, request, *args, **kwargs):
       serializer = MessagesSerializer(
            data=request.data
        )
       if serializer.is_valid():  # will call the validate function
          serializer.save()
          return Response({'success': True})
       else:
          return Response(
               serializer.errors,
               status=status.HTTP_400_BAD_REQUEST
          )

并在视图中使用它:

select t.name,
       (case when count(*) > 2 then 'y'
             else max(groupid)
        end)
from t;

答案 1 :(得分:1)

Model.save()是一个选项,尽管它validate input data在DRF序列化器中更常见,例如张贴的电话号码。

在哪里进行检查是您可以根据关注点分离的原则做出的决定。

答案 2 :(得分:1)

查看官方文档以了解如何完成此操作:https://docs.djangoproject.com/en/2.2/ref/models/instances/#django.db.models.Model.clean

  

此方法应用于提供自定义模型验证,并根据需要修改模型上的属性。例如,您可以使用它为字段自动提供一个值,或进行需要访问多个字段的验证:

def clean(self):
    # Don't allow draft entries to have a pub_date.
    if self.status == 'draft' and self.pub_date is not None:
        raise ValidationError(_('Draft entries may not have a publication date.'))
    # Set the pub_date for published items if it hasn't been set already.
    if self.status == 'published' and self.pub_date is None:
        self.pub_date = datetime.date.today()

实施一个clean方法,如果该方法检测到数据有问题,则会引发ValidationError。然后,您可以通过调用model_obj.full_clean()在视图中捕获它:

from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
try:
    article.full_clean()
except ValidationError as e:
    non_field_errors = e.message_dict[NON_FIELD_ERRORS]

答案 3 :(得分:1)

您要在保存之前验证字段。

有很多技术可以做到这一点。

对于您的情况,我建议选择第二种方法。覆盖文档中的方法clean_fields。然后在保存之前调用该方法。