Jekson
Jekson

Reputation: 3252

how do I properly set up data validation?

I have a DRF class which receives JSON date and after it has been processed, create new database instances.

class CsvToDatabase(APIView):

    def post(self, request, format=None):
        data = request.data
        print()
        for _, vendor in data.items():
            v = Vendors(
                vendor_name=vendor['Vendor'],
                country=vendor['Country'],
                nda=vendor['NDA date'],

            )
            try:
                v.full_clean()
            except ValidationError as e:
                data = ({'status': str(e)})
                return Response(data, content_type='application/json')
            v.save()
        return Response({'received data': request.data,
                         'message': 'Vendors from vendors_list were successfully added to the database'})

models.py

class Vendors(models.Model):
    COUNTRY_CHOICES = tuple(countries)

    ...
    country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
    nda = models.DateField(blank=True, null=True)
    ...

tuple(countries) looks like:

(..., ('AR', 'Argentina'), ('AM', 'Armenia'), ('AW', 'Aruba'), ('AU', 'Australia'), ('AT', 'Austria'), ('AZ', 'Azerbaijan'), ('BS', 'Bahamas'), ('BH', 'Bahrain'), ('BD', 'Bangladesh'), ('BB', 'Barbados'), ('BY', 'Belarus'), ('BE', 'Belgium'), ...)

Received JSON data may or may not contain the value of the nda field. An example of an incoming data format is as follows

{
    "1": {
        "Vendor": "Firstvendortestname",
        "Country": "Belgium,",
        "NDA date": "",
        "Primary Contact Name": "Jack Jhonson",
        "Primary Contact Email": "[email protected]",
        "Secondary Contact Name": "Jack2 Jhonson",
        "Secondary Contact Email": "[email protected]",
        "Modules": "Module1, Module2"
    },
    "2": {
        "Vendor": "Secondvendortestname",
        "Country": "Belarus",
        "NDA date": "2019-12-24",
        "Primary Contact Name": "Sandra Bullock",
        "Primary Contact Email": "[email protected]",
        "Secondary Contact Name": "Sandra Bullock",
        "Secondary Contact Email": "[email protected]",
        "Modules": "Module1, Module2"
    }
}

What's the problem.

A first one - "Country": "Belgium," get me error

{
    "status": "{'country': [\"Value 'Belgium' is not a valid choice.\"]}"
}

But if I change to "Country": "BE," it works.

A second one - "NDA date": "", get me error

ValidationError at /api/v1/vendors/from_csv_create/
["'' value has an invalid date format. It must be in YYYY-MM-DD format."]

Request Method: POST
Request URL: http://127.0.0.1:8000/api/v1/vendors/from_csv_create/
Django Version: 2.2.9
....
.....

But at models I have null=True and blank=True. And what is strange is that the second error is printed in text format instead of json as the first. Although in the exception, I specify return Response(data, content_type='application/json').

How do I get the ability to work with an empty nda field and set up my work with?

Upvotes: 0

Views: 56

Answers (1)

Jordan Kowal
Jordan Kowal

Reputation: 1594

For the 1st problem, it's because "Belgium" is not in your choices. Choice tuples are basically (accepted_value, human_readable_value). So when you write ("BE", "Belgium"), only "BE" will be considered as a valid choice. And it will be SHOWN as "Belgium" in your admin.

If you wanted to accept both (which might not be necessary), there are several ways to go:

  • Add more tuples : (("BE", "Belgium"), ("Belgium", "Belgium"))
  • Create a custom validator for the field

For your 2nd error "" is not valid date, it's because an empty string is not a valid value for a Date object in Django. Check out this topic, who had the same issue : DateTime Field shows invalid format error while passing empty value through form

Basically, you should either OMIT the field, or replace the "" value with None before pushing it

Upvotes: 1

Related Questions