【问题标题】:How to upload multiple images using modelformset - Django如何使用 modelformset 上传多个图像 - Django
【发布时间】:2015-12-29 14:28:43
【问题描述】:

我正在尝试创建一个系统,该系统允许用户添加新的蔬菜对象、上传缩略图以及多个图像和文件——所有这些都来自 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))

模板.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>

【问题讨论】:

  • 顺便说一句,如果您使用标题大小写,您的代码会更清晰,例如AddVegetableForm 用于表单类,小写例如vegetable_form 用于表单实例。使用VegetableForm = AddVegetableForm(request.POST) 会使其他用户感到困惑,因为VegetableForm 看起来像一个类,但它是一个实例。

标签: django django-forms modelform


【解决方案1】:

当你调用VegetableForm.save()时,它会返回实例,所以你应该这样做

vegetable = AddVegetableForm.save()

saving objects in a formset 上的文档建议调用formset.save(),它会返回一个实例列表。你可以用commit=False调用save(),设置蔬菜,然后保存到数据库。

images = formset.save(commit=False)
for image in images:
    image.vegetable = vegetable
    image.save()

【讨论】:

  • 你的第二个块替换了什么?
  • 它替换了处理有效表单集的代码,即循环for form in formset.cleaned_data:
  • 谢谢,一切似乎正常,但图片没有上传。
  • 您的表单标签中有错字 - enctypr 应该是 enctype
  • #我也有一个视图用于将绿色类别显示到 /vegetable/green-vegetable/ - 但它需要显示上传到该蔬菜的图像。我该怎么做? class GreenView(generic.ListView): model = Vegetable template_name = 'vegetable/green.html' context_object_name = 'green_vegetable' def get_queryset(self): return Vegetable.objects.filter(category__startswith="Green")
猜你喜欢
  • 2015-06-14
  • 2019-03-24
  • 2015-04-21
  • 2018-09-30
  • 2017-01-21
  • 2013-10-03
  • 2022-06-14
  • 1970-01-01
  • 2017-03-23
相关资源
最近更新 更多