简体   繁体   English

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

[英]Django: How to check if data is correct before saving it to a database on a post request?

I would like to be able to parse the data from a post request in my django rest api project by sending it to my function that will return true or false if the number is valid before saving it to the database and if it's wrong send a custom bad request message to the client that did the request. 我希望能够通过将其发送到我的函数来解析django rest api项目中来自发布请求的数据,如果该数字在保存到数据库之前是有效的,则返回true或false;如果错误,则发送自定义向执行请求的客户端发送的错误请求消息。

I've been told I can overwrite the create method todo this but I'm not sure how to go about it. 有人告诉我可以覆盖create方法来执行此操作,但是我不确定该如何执行。

My code so far looks like this: 到目前为止,我的代码如下所示:

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)

So basically just would like some direction on how to solve this problem. 所以基本上只是想对如何解决这个问题提供一些指导。 Even helpful links would be appreciated. 甚至有用的链接将不胜感激。 I did look on stackoverflow but was not successful, maybe I don't know how to phrase the question right when searching. 我确实看过stackoverflow,但没有成功,也许我不知道如何在搜索时说明问题。

You can use DRF Serializer's validation . 您可以使用DRF序列化器的验证 For example, create a serializer, and add a validation method naming validate_<field_name> . 例如,创建一个序列化器,并添加一个命名为validate_<field_name>的验证方法。 Then add the validation code there: 然后在其中添加验证代码:

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

And use it in the view: 并在视图中使用它:

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
          )

Model.save() is an option although it's more common to validate input data , like a phone number being posted, in the DRF Serializer. 尽管在DRF序列化器中验证输入数据 (例如张贴的电话号码)更常见,但Model.save()是一个选项。

Where to perform checks is a decision you can make based on the principal of separation of concerns. 您可以根据关注点分离的原则来决定在哪里进行检查。

Check the official documentation for how this is to be done: https://docs.djangoproject.com/en/2.2/ref/models/instances/#django.db.models.Model.clean 检查官方文档以了解如何完成此操作: https : //docs.djangoproject.com/en/2.2/ref/models/instances/#django.db.models.Model.clean

This method should be used to provide custom model validation, and to modify attributes on your model if desired. 应使用此方法提供自定义模型验证,并根据需要修改模型上的属性。 For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field: 例如,您可以使用它为字段自动提供一个值,或者进行需要访问多个字段的验证:

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()

Implement a clean method that will raise a ValidationError if it detects a problem with the data. 实现一个clean方法,如果它检测到数据问题,将引发ValidationError You can then catch this in the view by calling model_obj.full_clean() : 然后,您可以通过调用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]

You want to validate the fields before saving. 您要在保存之前验证字段。

There are quite a few techniques to do that. 有很多技术可以做到这一点。

For your scenario i would suggest second option. 对于您的情况,我建议第二个选择。 Override the method clean_fields as in documentation. 覆盖文档中的方法clean_fields。 Then call the method just before saving. 然后在保存之前调用该方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM