我正在try 允许每个用户上传多张图片到单个博客帖子.几天来,我一直在努力找出做这件事的最好方法.执行此操作的最佳实践是什么?

根据我所读到的,我应该从博客文章模型中创建一个单独的图像模型,并使用外键.是这样吗?

任何关于存储照片的最佳实践的建议也是受欢迎的.我看过亚马逊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')

您需要 for each 模型创建一个表单,但它们将相互关联,因为当用户填写表单帖子时,他也必须完成图像表单才能成功发布帖子,我们将在视图中完成此操作,但现在您的表单可能如下所示

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 formsets的地方.我们需要Django表单集才能实现这一点,您可以在Django文档中阅读有关表单集的信息,我已经链接了:)但以下是您的视图应该是什么样子:

*进口非常重要

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})

在视图中,我们得到了两个表单,它将判断两个表单是否有效.这样,用户必须填写表格并上传所有图片,在本例中,这些图片是3extra=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、htmx删除记录并更新

如何根据递归ManyToManyField值创建Django查询集?

如何自动删除 Django 模型中的字段值?

获取结果集中返回的元素数的 django 模板标签是什么?

是否有 django 模板过滤器来显示百分比?

Ruby on Rails 会影响网页的外观吗?

Django populate() 不可重入

Django unique=True 不工作

在 Django Admin 中过滤多对多框

更改 Django ModelChoiceField 以显示用户的全名而不是用户名

Django将HttpResponseRedirect返回到带有参数的url

如何在 Django 中使用动态外键?

Django:验证上传文件的文件类型

Django:在还原(迁移)后try 访问数据库时权限被拒绝

Django 在视图之间传递数据

Django 多项 Select 字段/复选框 Select 多个

想要在 Django 测试中禁用信号

确保只有一个工作人员在运行多个工作人员的 pyramid 网络应用程序中启动 apscheduler 事件

防止 django 管理员转义 html

Django 字符串到日期格式