使用模型表单上传 Django 文件

Django file upload with model form

有大量相关帖子:

我正在创建一个允许用户上传 css 文件的简单应用程序:

First, validate field field to make sure the file is css and the max size does not exceed 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

second, implement validation into model

models.py

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

third, create form for model creation

forms.py

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

last, write a callable view

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>

预期的结果是

不过,看来

for example, when I upload 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>