如何在 django 中正确保存多个文件?

Posted

技术标签:

【中文标题】如何在 django 中正确保存多个文件?【英文标题】:How correctly save multiple files in django? 【发布时间】:2017-10-21 14:54:49 【问题描述】:

我需要用户可以创建包含多个图像的文章的表单。我将django-multiupload 应用程序用于image 字段。我可以选择几张图片,但是当我尝试提交表单时,我在图片字段下有消息:"Field is empty and field is required"。我的错误在哪里?为什么图片字段不为空时会有这样的消息?

也许有人可以建议好的示例或应用程序来保存多张图像。如果有任何帮助,我将不胜感激。

models.py:

class Article(models.Model):
    description = models.TextField(_('Description'))

class Image(models.Model):
    article= models.ForeignKey(Article, on_delete=models.CASCADE)
    image = models.FileField(_('Image'), upload_to='images/%Y/%m/%d/')

forms.py:

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ('description', )

    image = MultiFileField()

    def save(self, commit=True):
        instance = super(ArticleForm, self).save(commit)
        for each in self.cleaned_data['image']:
            Image.objects.create(image=each, article=instance)
        return instance

views.py:

def article_add(request):
    data = dict()
    if request.method == 'POST':
        article_form = ArticleForm(request.POST, request.FILES)
        if article_form.is_valid():
            article = article_form.save(commit=False)
            ******
            article.save()
            data['form_is_valid'] = True
            articles = Article.objects.all
            context = 'articles': articles
            context.update(csrf(request))
            data['html_article'] = render_to_string('project/article_list.html', context)
        else:
            data['form_is_valid'] = False
    else:
        article_form = ArticleForm()
    context = 'article_form': article_form
    data['html_article_form'] = render_to_string('project/article_add.html', context, request=request)
    return JsonResponse(data)

article_add.html:

% load widget_tweaks %

<form method="post" action="% url 'article_add' %" class="article-add-form">
    % csrf_token %

    % for field in article_form %
    <div class="form-group% if field.errors % has-danger% endif %">
       <label class="form-control-label" for=" field.id_for_label "> field.label </label>
       % render_field field class="form-control" %
       % for error in field.errors %
          <div class="form-control-feedback"> error </div>
       % endfor %
    </div>
    % endfor %

    <button type="submit">Submit</button>
</form>

【问题讨论】:

【参考方案1】:

尝试在图像字段上添加“min_num”约束,

image = MultiMediaField(min_num=1, media_type='image')

编辑

def article_add(request):
    if request.method == 'POST':
        article_form = ArticleForm(request.POST, request.FILES)
        if article_form.is_valid():
            article = article_form.save(commit=False)
            ******
            article.save()
            #assume you have already a view in the name 'article_list'.
            return redirect('article_list')
    else:
        article_form = ArticleForm()
    context = dict(article_form=article_form)
    return render(request, 'project/article_add.html', context)

这个问题可能是因为你试图在一个视图中渲染两个模板,同样在使用 django 模板渲染时 render 是一个快捷功能,主要是首选使用,而不是字符串转换和解析成json。

另外,'article_list' 必须是另一个视图,它显示所有文章的列表,添加新文章后,您应该考虑重定向到列表视图。在这里,您尝试在单个视图中呈现多个模板。您可以在列表视图中制作类似的内容,

def article_list(request):
    articles = Article.objects.all()
    context = dict(articles=articles)
    return render(request, 'project/article_list.html', context)

不过,这些是我对您刚刚分享的代码的个人看法。试试这个方法...

【讨论】:

我有这个错误:TypeError: __init__() got an unexpected keyword argument 'media_type' 哦,那是MultiMediaField(),你可以试试……你只是上传图片不是吗? 或者 MultiImageField() 可以使用..,限制用户只能上传图片,使用 MultiFileField 可以上传任何文件类型... 我尝试了MultiFileFieldMultiImageField。我认为表单内部的save 方法不起作用。我将print("True") 放在 save 方法中只是为了测试。但是 PyCharm 控制台中什么都没有。你觉得我的保存方法对吗? 您的“需要图片”错误是否仍然存在??

以上是关于如何在 django 中正确保存多个文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Core Data 中正确保存?

如何在核心数据中正确保存可转换对象?

网页无法在谷歌浏览器中正确保存

如何在 Google App Engine 中正确实现多个模块的多个版本?

从Blob中正确保存C#中的.mp4文件[关闭]

如何在动态加载的 DLL 中正确实现(C++)线程本地存储?