如何在 django 中将多张图片上传到博客文章 [英] how to upload multiple images to a blog post in django

查看:49
本文介绍了如何在 django 中将多张图片上传到博客文章的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图允许每个用户将多张图片上传到单个博客文章.几天来,我一直在努力找出最好的方法来做到这一点.这样做的最佳做法是什么?

I am trying to allow each user to upload multiple pictures to a single blog post. I have been trying to work out the best way to do this for a few days now. What is the best practice to do this?

从我读到的内容来看,我应该从博客文章模型中创建一个单独的图像模型并使用外键.那正确吗?然后是如何允许他们同时上传多张图片的问题.我认为我应该使用放置区之类的东西是否正确?

From what I have read, I should make a seperate image model from the blog post model and use a foreign key. Is that right? Then there is the matter of how to allow them to upload multiple pictures at the same time. Am I right in assuming I should use something like drop zone?

也欢迎任何有关存储照片的最佳做法的建议.我看过亚马逊 s3 和 cloudinary.我想创造一些可扩展的东西.

Any advice on best practices for storing the photos is also welcome. I have looked at Amazon s3 and cloudinary. I want to create something which is scalable.

任何帮助将不胜感激!

推荐答案

您只需要两个模型.一个用于帖子,另一个用于图像.您的图像模型将具有 Post 模型的外键:

You'll just need two models. One for the Post and the other would be for the Images. Your image model would have a foreignkey to the Post model:

from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify

class Post(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=128)
    body = models.CharField(max_length=400)
  
def get_image_filename(instance, filename):
    title = instance.post.title
    slug = slugify(title)
    return "post_images/%s-%s" % (slug, filename)  


class Images(models.Model):
    post = models.ForeignKey(Post, default=None)
    image = models.ImageField(upload_to=get_image_filename,
                              verbose_name='Image')

您需要为每个模型创建一个表单,但它们将相互关联,例如当用户填写表单帖子时,他也必须完成图像表单才能成功发布帖子,并且我们将在视图中这样做,但现在您的表单看起来像这样

You need to create a form for each model, but they will be related to each other, as in when the user is filling out the form post he has to complete the image form too for the post to successfully be posted, and we shall do that in the views, but for now your form can look something like this

from django import forms
from .models import Post, Images

class PostForm(forms.ModelForm):
    title = forms.CharField(max_length=128)
    body = forms.CharField(max_length=245, label="Item Description.")
 
    class Meta:
        model = Post
        fields = ('title', 'body', )
 
 
class ImageForm(forms.ModelForm):
    image = forms.ImageField(label='Image')    
    class Meta:
        model = Images
        fields = ('image', )

现在这是所有内容中最重要的部分,即视图,因为这是将多个图像上传到单个魔术的地方.为了能够一次上传多张图片,我们需要多个图片字段,对吗?这就是您爱上 Django 表单集的地方.我们将需要 django 表单集来实现这一点,您可以在 Django 文档中阅读我已链接的表单集:) 但您的视图应该如下所示:

Now this is the most important part of everything, the views, because this is where uploading multiple images to a single magic happens. For us to be able to upload multiple images at once, we need multiple image fields right? That's where you fall in love with Django formsets. We will need django formsets to make this happen, you can read about formsets in the Django documentation, which I have linked :) But here is how your view should look like:

*非常重要的导入

from django.shortcuts import render
from django.forms import modelformset_factory
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import HttpResponseRedirect
from .forms import ImageForm, PostForm
from .models import Images

@login_required
def post(request):
 
    ImageFormSet = modelformset_factory(Images,
                                        form=ImageForm, extra=3)
    #'extra' means the number of photos that you can upload   ^
    if request.method == 'POST':
    
        postForm = PostForm(request.POST)
        formset = ImageFormSet(request.POST, request.FILES,
                               queryset=Images.objects.none())
    
    
        if postForm.is_valid() and formset.is_valid():
            post_form = postForm.save(commit=False)
            post_form.user = request.user
            post_form.save()
    
            for form in formset.cleaned_data:
                #this helps to not crash if the user   
                #do not upload all the photos
                if form:
                    image = form['image']
                    photo = Images(post=post_form, image=image)
                    photo.save()
            # use django messages framework
            messages.success(request,
                             "Yeeew, check it out on the home page!")
            return HttpResponseRedirect("/")
        else:
            print(postForm.errors, formset.errors)
    else:
        postForm = PostForm()
        formset = ImageFormSet(queryset=Images.objects.none())
    return render(request, 'index.html',
                  {'postForm': postForm, 'formset': formset})

在视图中,我们正在获取我们的两个表单,它会检查两个表单是否有效.这样,用户必须填写表格并上传所有图像,在这种情况下,为 3 extra=3.只有这样,帖子才能成功创建.

In the view, we are getting both of our forms, and it will check both forms whether they are valid or not. In that way, user has to fill the form AND upload all the images which, in this case, are 3 extra=3. Only then will the post successfully get created.

您的模板应该如下所示:

Your template should look like this then:

<form id="post_form" method="post" action="" enctype="multipart/form-data">
 
    {% csrf_token %}
    {% for hidden in postForm.hidden_fields %}
        {{ hidden }}
    {% endfor %}
 
    {% for field in postForm %}
        {{ field }} <br />
    {% endfor %}
 
    {{ formset.management_form }}
    {% for form in formset %}
        {{ form }}
    {% endfor %}
 
 
    <input type="submit" name="submit" value="Submit" />
</form>

这篇关于如何在 django 中将多张图片上传到博客文章的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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