Django: Как проверить правильность данных, прежде чем сохранять их в базе данных по запросу? - PullRequest
2 голосов
/ 02 апреля 2019

Я хотел бы иметь возможность проанализировать данные из запроса post в моем проекте 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 ]

3 голосов
/ 02 апреля 2019

Вы можете использовать проверку подлинности DRF Serializer .Например, создайте сериализатор и добавьте метод проверки с именем validate_<field_name>.Затем добавьте туда код подтверждения:

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
          )
1 голос
/ 02 апреля 2019

Вы хотите проверить поля перед сохранением.

Есть довольно много способов сделать это.

Для вашего сценария я бы предложил второй вариант. Переопределите метод clean_fields как в документации. Затем вызовите метод непосредственно перед сохранением.

1 голос
/ 02 апреля 2019

Проверьте официальную документацию, как это сделать: 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]
1 голос
/ 02 апреля 2019

Model.save () - опция, хотя она более распространена для проверки входных данных , например, номера телефона, публикуемого в Сериализаторе DRF.

Где выполнять проверкирешение, которое вы можете принять на основе принципа разделения интересов.

...