The Python Oracle

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

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Riding Sky Waves v001

--

Chapters
00:00 Django: How To Check If Data Is Correct Before Saving It To A Database On A Post Request?
01:04 Accepted Answer Score 8
01:38 Answer 2 Score 2
02:29 Answer 3 Score 1
02:52 Answer 4 Score 1
03:32 Thank you

--

Full question
https://stackoverflow.com/questions/5547...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #django #api #validation #djangorestframework

#avk47



ACCEPTED ANSWER

Score 8


You can use DRF Serializer's validation. For example, create a serializer, and add a validation method naming 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
          )



ANSWER 2

Score 2


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

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. You can then catch this in the view by calling 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]



ANSWER 3

Score 1


Model.save() is an option although it's more common to validate input data, like a phone number being posted, in the DRF Serializer.

Where to perform checks is a decision you can make based on the principal of separation of concerns.




ANSWER 4

Score 1


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. Then call the method just before saving.