Расширение поля формы для добавления новых проверок - PullRequest
2 голосов
/ 29 апреля 2010

Я написал приложение, которое использует формы для сбора информации, которая затем отправляется по электронной почте. Многие из этих форм имеют файловое поле, используемое для прикрепления файлов к электронной почте. Я хотел бы проверить две вещи, размер файла (чтобы убедиться, что электронные письма принимаются нашим почтовым сервером. Я также хотел бы проверить расширение файла, чтобы не допускать присоединения файлов, которые не могут использоваться нашими пользователями.

(это класс Python, который я пытаюсь расширить)

class FileField(Field):
    widget = FileInput
    default_error_messages = {
        'invalid': _(u"No file was submitted. Check the encoding type on the form."),
        'missing': _(u"No file was submitted."),
        'empty': _(u"The submitted file is empty."),
        'max_length': _(u'Ensure this filename has at most %(max)d characters (it has %(length)d).'),
    }

    def __init__(self, *args, **kwargs):
        self.max_length = kwargs.pop('max_length', None)
        super(FileField, self).__init__(*args, **kwargs)

    def clean(self, data, initial=None):
        super(FileField, self).clean(initial or data)
        if not self.required and data in EMPTY_VALUES:
            return None
        elif not data and initial:
            return initial

        # UploadedFile objects should have name and size attributes.
        try:
            file_name = data.name
            file_size = data.size
        except AttributeError:
            raise ValidationError(self.error_messages['invalid'])

        if self.max_length is not None and len(file_name) > self.max_length:
            error_values =  {'max': self.max_length, 'length': len(file_name)}
            raise ValidationError(self.error_messages['max_length'] % error_values)
        if not file_name:
            raise ValidationError(self.error_messages['invalid'])
        if not file_size:
            raise ValidationError(self.error_messages['empty'])
    return data

Ответы [ 3 ]

2 голосов
/ 29 апреля 2010

Просто перегрузите «чистый» метод:

def clean(self, data, initial=None):
    try:
        if data.size > somesize:
            raise ValidationError('File is too big')

        (junk, ext) = os.path.splitext(data.name)
        if not ext in ('.jpg', '.gif', '.png'):
            raise ValidationError('Invalid file type')

    except AttributeError:
        raise ValidationError(self.error_messages['invalid'])

    return FileField.clean(self, data, initial)
1 голос
/ 29 апреля 2010

по моему мнению, создание подкласса для фактического класса поля - это путь больших усилий. Должно быть проще расширить класс формы. Вы можете добавить метод, который «очищает» поле файла.

Например:

class MyForm(forms.Form):
  attachment = forms.FileField(...)

  def clean_attachment(self):
    data = self.cleaned_data['attachment'] // UploadedFile object
    exts = ['jpg', 'png'] // allowed extensions

    // 1. check file size
    if data.size > x:
      raise forms.ValidationError("file to big")

    // 2. check file extension
    file_extension = data.name.split('.')[1] // simple method

    if file_extension not in exts:
      raise forms.ValidationError("Wrong file type")

    return data

Это только базовый пример, и здесь есть некоторые грубые края. Но вы можете использовать этот пример и улучшать его, пока у вас не появится версия, которая работает для вас.

Рекомендуемые значения:

Django Doc - Очистка определенного поля

Django Doc - класс загруженных файлов

Django Doc - Класс файла

0 голосов
/ 29 апреля 2010

Вот что я закончил:

В файле настроек моего приложения:

exts = ['doc', 'docx', 'pdf', 'jpg', 'png', 'xls', 'xlsx', '.xlsm', '.xlsb']
max_email_attach_size = 10485760 #10MB written in bytes

В новом файле я назвал formfunctions:

from django import forms
from django.forms.util import ErrorList, ValidationError
from app.settings import exts, max_email_attach_size


class SizedFileField(forms.FileField):

    def clean(self, data, initial=None):

        if not data in (None, ''):

            try:
                if data.size > max_email_attach_size:
                    raise ValidationError("The file is too big")

                file_extension = data.name.split('.')[1]
                if file_extension not in exts:
                    raise ValidationError("Invalid File Type")

            except AttributeError:
                raise ValidationError(self.error_messages['invalid'])

        return forms.FileField.clean(self, data, initial)

и в моем файле форм:

from formfunctions import SizedFileField

Пример класса из файла форм:

class ExampleClass(forms.Form):
    Email_Body = forms.CharField(widget=forms.Textarea, required=False)
    Todays_Date = forms.CharField()
    Attachment = SizedFileField(required=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...