Загрузка файлов в Django с помощью формы модели

здесь тонны соответствующих постов:

Я создаю простое приложение, которое позволяет пользователю загружать css файл:

Сначала проверьте поле, чтобы убедиться, что файл является css и максимальный размер не превышает 5MB.

fields.py

from django.db import models
from django import forms
from django.template.defaultfilters import filesizeformat


def mb(n):
    return n * 1048576


class FileField(models.FileField):
    def __init__(self, *args, **kwargs):
        self.content_types = kwargs.pop('content_types', [])
        self.max_upload_size = kwargs.pop('max_upload_size', [])
        super().__init__(*args, **kwargs)
    
    def clean(self, *args, **kwargs):
        data = super().clean(*args, **kwargs)
        file = data.file

        try:
            content_type = file.content_type
            if content_type in self.content_types:
                if file.size > self.max_upload_size:
                    raise forms.ValidationError('Please keep filesize under {}. Current filesize {}'
                    .format(filesizeformat(self.max_upload_size), filesizeformat(file.size)))
            else:
                raise forms.ValidationError('File type rejected')
        except AttributeError:
            pass
        return data

во-вторых, внедрить валидацию в модель

models.py

# Create your models here.
class Css(models.Model):
    file = FileField(
        upload_to='css', 
        content_types=['text/css'],
        max_upload_size=mb(5),
    )

в-третьих, создайте форму для создания модели

forms.py

class CssCreateForm(forms.ModelForm):
    class Meta:
        model = Css
        fields = ['file']

в заключение напишите вызываемое представление

views.py

# Create your views here.
def cssUploadView(request):
    if request.method == 'POST':
        print(request.POST['file'])
        print(type(request.POST['file']))
        print(request.FILES)
        form = forms.CssCreateForm(request.POST, request.FILES)
        if form.is_valid():
            print('---------')
            print(form.cleaned_data['file'])
        else:
            print('not valid')
    else:
        form = forms.CssCreateForm()
        return render(request, 'css/css_create.html', {
            'form': form,
        })

template

<form method="POST">
    {% csrf_token %}
    <div class="form-title">Upload a new CSS file</div>
    {{ form.as_p }}
    <div class="button-area">
        <button id="go" type="submit">Go</button>
    </div>
</form>

Ожидаемый результат:

  • при загрузке html файла или css файла размером более 5MB, ValidationError будет поднят вопрос
  • .

Однако, с точки зрения

  • И request.FILES, и form.cleaned_data['file'] не удается получить загруженный файл.
  • form.is_valid всегда возвращает True
  • .

например, когда я загружаю clean.py:

clean.py
<class 'str'>
<MultiValueDict: {}>
---------
None

Интересно, почему файл не загружается и валидация не работает? Любое предложение будет оценено по достоинству.

Вы должны указать метод кодирования данных в вашей html-форме.

<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <div class="form-title">Upload a new CSS file</div>
    {{ form.as_p }}
    <div class="button-area">
        <button id="go" type="submit">Go</button>
    </div>
</form>
Вернуться на верх