django - 如何在 django 中将多张图片上传到博客文章

标签 django image amazon-s3 image-uploading cloudinary

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

根据我的阅读,我应该从博客文章模型中创建一个单独的图像模型并使用外键。是对的吗?
然后是如何让他们同时上传多张图片的问题。我是否正确地假设我应该使用像 drop zone 之类的东西?

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

任何帮助将非常感激!

最佳答案

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

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')
您需要为每个模型创建一个表单,但它们将相互关联,因为当用户填写表单时,他也必须完成图像表单才能成功发布帖子,我们会这样做在 View 中,但现在你的表单看起来像这样
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', )
现在这是所有内容中最重要的部分,即 View ,因为这是将多个图像上传到单个魔术的地方。为了让我们能够一次上传多张图片,我们需要多个图片字段,对吗?那就是你爱上 Django formsets 的地方.我们将需要 django 表单集来实现这一点,您可以阅读我已链接的 Django 文档中的表单集:) 但您的 View 应如下所示:
*非常重要的进口
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})
在 View 中,我们得到了两个表单,它将检查两个表单是否有效。这样,用户必须填写表格并上传所有图像,在这种情况下,是 3 extra=3 .只有这样才能成功创建帖子。
您的模板应如下所示:
<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 - 如何在 django 中将多张图片上传到博客文章,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34006994/

相关文章:

javascript - D3.js "exporting"数据

sql - 我们如何才能获得所有用户名列表而不是使用 django ORM 的用户对象

django - Django达到序列的最大值

multithreading - Delphi EOutOfResources 屏幕截图

image - OpenCV - 从图像中删除水平点或线导致图像质量较低

java - 无法获得 instagram 个人资料图片全尺寸

ruby-on-rails - 如何从 S3 获取文件大小和类型?

python - 如何统计与ListView中显示的项目相关的对象?

java - AmazonS3Client 已弃用如何使用凭证获取 s3client 对象

java - AWS SDK Java TransferManager 限制下载大小