如何使用modelformset上传多个图像 - Django [英] How to upload multiple images using modelformset - Django

查看:214
本文介绍了如何使用modelformset上传多个图像 - Django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个系统,允许用户添加一个新的Vegetable对象,上传缩略图和多个图像和文件 - 所有这些都可以从AddVegetable页面进行,并且能够很容易地输出这些植物类型被过滤以显示在不同的页面上



我试图通过下面的代码来实现这一点,但是它不会工作,我无法弄清楚为什么会这样我得到一个KeyError'图像',但我不知道为什么。我正在这样做正确的方式吗?



我目前无视图像处理,



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):
蔬菜= models.ForeignKey(蔬菜,默认=无)
image = models.ImageField(upload_to ='图像/蔬菜',
verbose_name = 'image',)

forms.py

 类AddVegetable(ModelFor m):
class Meta:
model = Vegetable
fields = ['title','category','description','thumbnail',
'images','附件','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)

如果request.method =='POST':

VegetableForm = AddVegetableForm(request.POST)
formset = ImageFormSet(request.POST,request.FILES,
queryset = VegetableImage.objects.none())

如果VegetableForm.is_valid()和formset.is_valid():

VegetableForm.save()

为formset.cleaned_data中的表单:
image = form ['image']
picture = VegetableImage(vegetable = VegetableForm,image = image)
picture.save()

return HttpResponseRedirect('/ vegetable /')
else:
打印(VegetableForm.errors,formset.errors)

else:
VegetableForm = AddVegetableForm()
formset = ImageFormSet(queryset = VegetableImage.objects.none())

返回渲染(request,'vegetable / add.html',
{'VegetableForm':VegetableForm, formset':formset},
context_instance = RequestContext(request))

template.html

 < form action =/ vegetable / add /method =POSTenctypr =multipart / form-data> ; 
{%csrf_token%}
< table>

< p> {{VegetableForm.as_ul}}< / p>

{{formset.management_form}}
{form for formset%}
{{form}}
{%endfor%}

< / table>

< input type =submitvalue =Post>
< / form>


解决方案

当您调用 VegetableForm时。 save(),它返回实例,所以你应该做

  vegetable = AddVegetableForm.save )

在表单集中保存对象建议调用 formset.save(),它返回一个实例列表。您可以使用 commit = False 调用 save(),设置蔬菜,然后保存到数据库。

  images = formset.save(commit = False)
图像中的图像:
image.vegetable =蔬菜
image.save()


I am trying to create a system which allows a user to be able to add a new Vegetable object, upload a thumbnail and multiple images and files - all from the AddVegetable page, and be able to output this easily as the vegetable types are filtered to display on different pages

I'm trying to achieve this with the code below but it won't work and I cant figure out why exactly, as it stands I'm getting a KeyError 'image', but I don't know why. I am going about this the right way at all?

I am ignoring image processing for the moment,

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>

解决方案

When you call VegetableForm.save(), it returns the instance, so you should do

vegetable = AddVegetableForm.save()

The docs on saving objects in a formset suggest calling formset.save(), which returns a list of instances. You can call save() with commit=False, set the vegetable, then save to the database.

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

这篇关于如何使用modelformset上传多个图像 - Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆