如何使用 modelformset 上传多张图片 - Django
How to upload multiple images using modelformset - Django
我正在尝试创建一个系统,允许用户添加新的 Vegetable 对象、上传缩略图和多个图像和文件 - 所有这些都来自 AddVegetable 页面,并且能够轻松地将其输出为筛选蔬菜类型显示在不同的页面
我正在尝试使用下面的代码实现此目的,但它不起作用,而且我无法弄清楚为什么会出现 KeyError 'image',但我没有知道为什么。我的做法完全正确吗?
我暂时忽略图像处理,
models.py
class Vegetable(models.Model):
title = models.CharField(max_length=0)
category = models.CharField(max_length=50,
choices=CATEGORY_CHOICES)
description = models.CharField(max_length=1000, null=True)
thumbnail = models.ImageField(upload_to = 'uploaded_images/')
attachments = models.FileField(upload_to = uploaded_files/)
date_added = models.DateTimeField('Date Added', default=datetime.datetime.now)
class VegetableImage(models.Model):
vegetable = models.ForeignKey(Vegetable, default=None)
image = models.ImageField(upload_to='images/vegetable',
verbose_name='image',)
forms.py
Class AddVegetable(ModelForm):
class Meta:
model = Vegetable
fields = ['title', 'category', 'description', 'thumbnail',
'images', 'attachments', 'date_added',]
class ImageForm(ModelForm):
image = ImageField(label='image')
class Meta:
model = VegetableImage
fields = ['image',]
views.py
def AddVegetable(request):
ImageFormSet = modelformset_factory(VegetableImage,
form=ImageForm, extra=4)
if request.method == 'POST':
VegetableForm = AddVegetableForm(request.POST)
formset = ImageFormSet(request.POST, request.FILES,
queryset=VegetableImage.objects.none())
if VegetableForm.is_valid() and formset.is_valid():
VegetableForm.save()
for form in formset.cleaned_data:
image = form['image']
picture = VegetableImage(vegetable=VegetableForm, image=image)
picture.save()
return HttpResponseRedirect('/vegetable/')
else:
print (VegetableForm.errors, formset.errors)
else:
VegetableForm = AddVegetableForm()
formset = ImageFormSet(queryset=VegetableImage.objects.none())
return render(request, 'vegetable/add.html',
{'VegetableForm': VegetableForm, 'formset': formset},
context_instance=RequestContext(request))
template.html
<form action="/vegetable/add/" method="POST" enctypr="multipart/form-data">
{% csrf_token %}
<table>
<p> {{ VegetableForm.as_ul }}</p>
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
{% endfor %}
</table>
<input type="submit" value="Post">
</form>
当你调用VegetableForm.save()
时,它returns实例,所以你应该
vegetable = AddVegetableForm.save()
saving objects in a formset 上的文档建议调用 formset.save()
,其中 returns 是一个实例列表。你可以用commit=False
调用save()
,设置蔬菜,然后保存到数据库。
images = formset.save(commit=False)
for image in images:
image.vegetable = vegetable
image.save()
我正在尝试创建一个系统,允许用户添加新的 Vegetable 对象、上传缩略图和多个图像和文件 - 所有这些都来自 AddVegetable 页面,并且能够轻松地将其输出为筛选蔬菜类型显示在不同的页面
我正在尝试使用下面的代码实现此目的,但它不起作用,而且我无法弄清楚为什么会出现 KeyError 'image',但我没有知道为什么。我的做法完全正确吗?
我暂时忽略图像处理,
models.py
class Vegetable(models.Model):
title = models.CharField(max_length=0)
category = models.CharField(max_length=50,
choices=CATEGORY_CHOICES)
description = models.CharField(max_length=1000, null=True)
thumbnail = models.ImageField(upload_to = 'uploaded_images/')
attachments = models.FileField(upload_to = uploaded_files/)
date_added = models.DateTimeField('Date Added', default=datetime.datetime.now)
class VegetableImage(models.Model):
vegetable = models.ForeignKey(Vegetable, default=None)
image = models.ImageField(upload_to='images/vegetable',
verbose_name='image',)
forms.py
Class AddVegetable(ModelForm):
class Meta:
model = Vegetable
fields = ['title', 'category', 'description', 'thumbnail',
'images', 'attachments', 'date_added',]
class ImageForm(ModelForm):
image = ImageField(label='image')
class Meta:
model = VegetableImage
fields = ['image',]
views.py
def AddVegetable(request):
ImageFormSet = modelformset_factory(VegetableImage,
form=ImageForm, extra=4)
if request.method == 'POST':
VegetableForm = AddVegetableForm(request.POST)
formset = ImageFormSet(request.POST, request.FILES,
queryset=VegetableImage.objects.none())
if VegetableForm.is_valid() and formset.is_valid():
VegetableForm.save()
for form in formset.cleaned_data:
image = form['image']
picture = VegetableImage(vegetable=VegetableForm, image=image)
picture.save()
return HttpResponseRedirect('/vegetable/')
else:
print (VegetableForm.errors, formset.errors)
else:
VegetableForm = AddVegetableForm()
formset = ImageFormSet(queryset=VegetableImage.objects.none())
return render(request, 'vegetable/add.html',
{'VegetableForm': VegetableForm, 'formset': formset},
context_instance=RequestContext(request))
template.html
<form action="/vegetable/add/" method="POST" enctypr="multipart/form-data">
{% csrf_token %}
<table>
<p> {{ VegetableForm.as_ul }}</p>
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
{% endfor %}
</table>
<input type="submit" value="Post">
</form>
当你调用VegetableForm.save()
时,它returns实例,所以你应该
vegetable = AddVegetableForm.save()
saving objects in a formset 上的文档建议调用 formset.save()
,其中 returns 是一个实例列表。你可以用commit=False
调用save()
,设置蔬菜,然后保存到数据库。
images = formset.save(commit=False)
for image in images:
image.vegetable = vegetable
image.save()