使用模型表单上传 Django 文件
Django file upload with model form
有大量相关帖子:
- https://docs.djangoproject.com/en/3.2/topics/http/file-uploads/
- Uploading A file in django with ModelForms
- https://github.com/axelpale/minimal-django-file-upload-example
我正在创建一个允许用户上传 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>
预期的结果是
- 上传html文件时,或css文件大于5MB时,
ValidationError
会提升
不过,看来
request.FILES
和 form.cleaned_data['file']
都无法检索上传的文件。
form.is_valid
总是returnsTrue
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>
有大量相关帖子:
- https://docs.djangoproject.com/en/3.2/topics/http/file-uploads/
- Uploading A file in django with ModelForms
- https://github.com/axelpale/minimal-django-file-upload-example
我正在创建一个允许用户上传 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>
预期的结果是
- 上传html文件时,或css文件大于5MB时,
ValidationError
会提升
不过,看来
request.FILES
和form.cleaned_data['file']
都无法检索上传的文件。form.is_valid
总是returnsTrue
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>