Login

CSVField for forms

Author:
AgustinLado
Posted:
December 22, 2016
Language:
Python
Version:
Not specified
Score:
0 (after 0 ratings)

FileField that checks that the file is a valid CSV and if specified in expected_fieldnames checks that the fields match exactly.

The widget's accept parameter is set to accept csv, text and excel files.

TODO: Validate the entirety of the CSV file, not just the headers. But this should be enough for most use cases, as checking the whole file could be computationally expensive for huge files.

Example usage: people = CSVField(expected_fieldnames=['First Name', 'Last Name'])

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import csv

from django import forms
from django.core.exceptions import ValidationError


class CSVField(forms.FileField):
    """
    FileField that checks that the file is a valid CSV and if specified
    in `expected_fieldnames` checks that the fields match exactly.

    The widget's `accept` parameter is set to accept csv, text and excel files.

    TODO: Validate the entirety of the CSV file, not just the headers.
          But this should be enough for most use cases, as checking the 
          whole file could be computationally expensive for huge files.

    Example usage:
        people = CSVField(expected_fieldnames=['First Name', 'Last Name'])
    """

    def __init__(self, *args, **kwargs):
        self.expected_fieldnames = kwargs.pop('expected_fieldnames', None)
        super(CSVField, self).__init__(*args, **kwargs)
        self.error_messages['required'] = 'You must select a file'
        self.widget.attrs.update(
            {'accept': '.csv,'
                       'text/plain,'
                       'application/vnd.ms-excel,'
                       'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})

    def clean(self, data, initial=None):
        value = super(CSVField, self).clean(data)
        reader = csv.reader(data)
        # Check it's a valid CSV file
        try:
            fieldnames = reader.next()
        except csv.Error:
            raise ValidationError('You must upload a valid CSV file')

        # Check the fieldnames are as specified, if requested
        if self.expected_fieldnames and fieldnames != self.expected_fieldnames:
            raise ValidationError(
                u'The CSV fields are expected to be "{0}"'.format(
                    u','.join(self.expected_fieldnames)))

        return value

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 3 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 3 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 10 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 11 months ago
  5. Help text hyperlinks by sa2812 12 months ago

Comments

Please login first before commenting.