python - Django formset 为多张图片上传创建多个输入

标签 python django

我正在尝试创建一个像这样的简单帖子共享表单。

enter image description here

我正在使用 formset 进行图像上传。但这给了我多种输入,如您所见。每个输入也可以选择单个图像。但我正在尝试使用单个输入上传多个图像。

View .py

def share(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 = postForm.save(commit=False)
            post.author = request.user
            post.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, image=image)
                    photo.save()

            return redirect("index")

        else:
            print(postForm.errors, formset.errors)
    else:
        postForm = PostForm()
        formset = ImageFormSet(queryset=Images.objects.none())
    return render(request, "share.html", {"postForm": postForm, 'formset': formset})

分享.html
 <form  method="POST" id="post-form" class="post-form js-post-form" enctype="multipart/form-data">
            {% csrf_token %}
             {{ formset.management_form }}
                {% for form in formset %}
                    {{ form }}
                {% endfor %} 
   </form>

如果你需要,forms.py
class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ["title", "content"]

    def __init__(self, *args, **kwargs):
        super(PostForm, self).__init__(*args, **kwargs)
        self.fields['title'].widget.attrs.update({'class': 'input'})
        self.fields['content'].widget.attrs.update({'class': 'textarea'})


class ImageForm(forms.ModelForm):
    image = forms.ImageField(label='Image')

    class Meta:
        model = Images
        fields = ('image', )

        def __init__(self, *args, **kwargs):
            self.fields['image'].widget.attrs.update(
                {'class': 'fileinput', 'multiple': True})

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


class Post(models.Model):
    # on_delete ile, bu kullanıcı silindiğinde bu kullanıcıya ait tüm postlar da silinecek.
    author = models.ForeignKey(
        "auth.User", on_delete=models.CASCADE, verbose_name="Yazar")
    title = models.CharField(max_length=150, verbose_name="Başlık")
    content = models.TextField(verbose_name="İçerik")
    # auto_now_add = True ile veritabanına eklendiği tarihi otomatik alacak
    created_date = models.DateTimeField(auto_now_add=True)

    # admin panelinde Post Object 1 yazması yerine başlığı yazsın istersek...
    def __str__(self):
        return self.title


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, on_delete=models.DO_NOTHING, default=None)
    image = models.ImageField(upload_to=get_image_filename,
                              verbose_name='Image', default="images/default_game_img.png")

最佳答案

如果您需要为多张图片上传一个文件,请尝试以下操作:

View .py

from .forms import PostForm
from .models import Post, Images

def share(request):
    form = PostForm()

    if request.method == 'POST':
        post = Post()
        post.title = request.POST['title']
        post.content = request.POST['content']
        post.author = request.user
        post.save()

        for image in request.FILES.getlist('images'):
            image_obj = Image()
            image_obj.post_id = post.id
            image_obj.image = image
            image_obj.save()

    return render(request, 'share.html', {'form': form})

表格.py
from django import forms

class PostForm(forms.Form):
    title = forms.CharField(label='', 
                        widget=forms.TextInput(attrs={
                            'class': 'input',
                            }
                        )) 

    content = forms.CharField(label='', 
                           widget=forms.Textarea(attrs={
                               'class': 'textarea',
                               }
                           ))                    

    images = forms.ImageField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

分享.html
<form  method="POST" id="post-form" class="post-form js-post-form" enctype="multipart/form-data">
            {% csrf_token %}
            {% for elem in form %}
                {{ elem }}
            {% endfor %}
</form>

关于python - Django formset 为多张图片上传创建多个输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960889/

相关文章:

django - 使用用户 ID 保存模型表单?

jquery - Django 评级和 Jquery 集成?

python - 如何让virtualenv Django服务器工作?//根据命令提示符 'missing attribute'

python - 如何使用 cassandra python-driver 实现基于 token 的分页?

java - 算法 - 如何有效地删除列表中的重复元素?

python - 如何在 django-rest-framework 序列化器中使用时区序列化时间?

python - Roi自定义OpenCV

python - Nuke 中的 Pyside 小部件不保持值

Django 1.5 索引页

javascript - Django:如果url是用户手动编写的,则重定向