如何在django中将多个图像上载到博客帖子

如何在django中将多个图像上载到博客帖子,django,image,amazon-s3,image-uploading,cloudinary,Django,Image,Amazon S3,Image Uploading,Cloudinary,我试图让每个用户上传多张图片到一个博客帖子。几天来,我一直在努力找出最好的方法。这样做的最佳实践是什么 根据我所读到的,我应该从博客文章模型中创建一个单独的图像模型,并使用外键。是这样吗? 然后是如何允许他们同时上传多张图片的问题。我认为我应该使用像下降区这样的东西,对吗 任何关于存储照片的最佳实践的建议都是欢迎的。我已经看过AmazonS3和cloudinary。我想创建一些可伸缩的东西 任何帮助都将不胜感激 您只需要两个型号。一个是帖子,另一个是图片。您的图像模型将具有Post模型的fore

我试图让每个用户上传多张图片到一个博客帖子。几天来,我一直在努力找出最好的方法。这样做的最佳实践是什么

根据我所读到的,我应该从博客文章模型中创建一个单独的图像模型,并使用外键。是这样吗? 然后是如何允许他们同时上传多张图片的问题。我认为我应该使用像下降区这样的东西,对吗

任何关于存储照片的最佳实践的建议都是欢迎的。我已经看过AmazonS3和cloudinary。我想创建一些可伸缩的东西


任何帮助都将不胜感激

您只需要两个型号。一个是帖子,另一个是图片。您的图像模型将具有Post模型的foreignkey:

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

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', )
现在这是所有事情中最重要的部分,视图,因为这是将多个图像上传到单个magic的地方。为了让我们能够一次上传多个图像,我们需要多个图像字段,对吗?那就是你爱上Django的地方。我们需要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})
在视图中,我们得到了两个表单,它将检查两个表单是否有效。这样,用户必须填写表单并上传所有图像,在本例中,这些图像是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>

{%csrf_令牌%}
{%用于postForm.hidden_字段%}
{{隐藏}}
{%endfor%}
{postForm%中字段的%s}
{{field}}
{%endfor%} {{formset.management_form} {formset%中表单的%s} {{form}} {%endfor%}
我也有类似的问题。在我的模型中,一篇文章必须有一个缩略图(图像),然后我为可选图像设置了另外五个字段。当应用安全过滤器后,图像源将无法呈现,因为它不再是HTML


一步一步解决方案=>即使如此,我也被卡住了。这就是我如何成功地做到的

最后
实现下面的代码,我实现了这一点

  • 1个带有多个图像的注释模型
  • 多次上传(在同时,使用相同的选择文件按钮,将所有内容保存在一起,就像在Gmail文件上传中一样
这是我的笔记和图像模型-(或)

这是我的表格()-(或)

这是我的视图文件-(或)

最后,我的Html文件()-(或)

{%csrf\u令牌%}
标题
描述
图像
提交

答案很简单。不需要这么多代码

HTML文件

<input type="file" name = "files" multiple />

getlist名称和html输入名称字段应该相同

适用于型号.py

class studentImage(models.Model):
        image = models.ImageField(upload_to='media/')
    
        def __str__(self):
            return self.image
def studentImageView(request):
    if request.method == "POST":
        images = request.FILES.getlist('images')
        for image in images:
            photo = studentImage.objects.create(image=image,)
            photo.save()

    return render(request, 'image.html')
用于视图。py

class studentImage(models.Model):
        image = models.ImageField(upload_to='media/')
    
        def __str__(self):
            return self.image
def studentImageView(request):
    if request.method == "POST":
        images = request.FILES.getlist('images')
        for image in images:
            photo = studentImage.objects.create(image=image,)
            photo.save()

    return render(request, 'image.html')
用于模板

<form method="post" enctype="multipart/form-data" >
  {% csrf_token %}
   <input required name="images" type="file" multiple >
  <button class="btn btn-primary" type="submit">Upload</button>
</form>

{%csrf_令牌%}
上传

添加多个图像上传或其他方式的一种方法是使用django ckeditor并使用其图像上传插件,其中图像上传到amazon s3存储,并且只有img标签插入到您的内容中,并将正确的地址添加到s3图像位置非常感谢!您如何将dropzone js这样的拖放系统整合到其中?如果你想使用拖放方法,你需要表单集吗?@ollysmall很抱歉我不能帮你,我对Javascript一无所知,所以我无法告诉你你会怎么做。但是看看这个,我试着完全按照你的要求去做,我发现django jquery文件上传了,但我不知道如何使用它以及如何使用表单集。试试看吧?@qasimalbaqali我参加聚会迟到了,但我有一个稍微不同的问题。希望你能帮我解决这个问题。这个管理员应该是什么样子?@bgarcial抱歉,我已经有一段时间没联系django了,我帮不了你。但也许这会有帮助
class studentImage(models.Model):
        image = models.ImageField(upload_to='media/')
    
        def __str__(self):
            return self.image
def studentImageView(request):
    if request.method == "POST":
        images = request.FILES.getlist('images')
        for image in images:
            photo = studentImage.objects.create(image=image,)
            photo.save()

    return render(request, 'image.html')
<form method="post" enctype="multipart/form-data" >
  {% csrf_token %}
   <input required name="images" type="file" multiple >
  <button class="btn btn-primary" type="submit">Upload</button>
</form>