python Django上传了很多图片到模型区域

tyu7yeag  于 2023-03-16  发布在  Python
关注(0)|答案(3)|浏览(163)

我在django中有一个项目负责创建带有可选添加图像的注解。现在我可以添加最多一个图像的注解。我想允许用户添加尽可能多的图像,但我不知道如何添加。我尝试在模型字段中使用ArrayField,但它不起作用。我想这样:当用户点击“添加图像”,浏览器显示,他可以选择多个图像。然后这些图像保存到一个模型示例。例如,如果img字段将是数组数据库中的字段将是:img = ['image1.jpg','image2.jpg','image3.jpg'],我不想创建与要上传的图像一样多的对象。
我的模特:

class Note(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='note', null=True)
    title = models.CharField(max_length=200)
    note_text = models.TextField()
    add_date = models.DateTimeField('added date')
    img = models.ImageField(upload_to='images', blank=True)
    edit_dates = ArrayField(
        models.DateTimeField('edit dates', blank=True, null=True),
        default=list,
    )

    def __str__(self):
        return self.title

我的表单:

class AddNewNote(forms.ModelForm):
    class Meta:
        model = Note
        fields = ['title', 'note_text', 'img', ]

我的观点:

class CreateNoteView(CreateView):
    model = Note
    template_name = 'notes/add_note.html'
    form_class = AddNewNote

    def get_success_url(self):
        return reverse('show', kwargs={'pk' : self.object.pk})

    def form_valid(self, form):
        form.instance.add_date = timezone.now()
        form.instance.user = self.request.user
        return super(CreateNoteView, self).form_valid(form)

和add_note.html:

{% extends 'notes/base.html' %}

{% block title %} Add new note {% endblock %}

{% load crispy_forms_tags %}

{% block content %}
    <h1 class="display-4">Add new note</h1>
    <form method="POST" class="m-5" action="#" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form|crispy }}
        <button type="submit" name="add" class="btn btn-primary">Save</button>
    </form>
{% endblock %}
jk9hmnmh

jk9hmnmh1#

要将多个图像上载到单个Note示例,请修改您的Note模型以使用ManyToManyField将多个图像示例关联到单个Note示例。

class Note(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='note', null=True)
    title = models.CharField(max_length=200)
    note_text = models.TextField()
    add_date = models.DateTimeField('added date')
    edit_dates = ArrayField(
        models.DateTimeField('edit dates', blank=True, null=True),
        default=list,
    )
    images = models.ManyToManyField('Image', blank=True)

    def __str__(self):
        return self.title

class Image(models.Model):
    image = models.ImageField(upload_to='images')

    def __str__(self):
        return self.image.name

AddNewNote表单中,将img字段替换为ModelMultipleChoiceField以允许用户选择多个图像

from django.forms.widgets import ClearableFileInput

class AddNewNote(forms.ModelForm):
    images = forms.ImageField(widget=ClearableFileInput(attrs={'multiple': True}), required=False)

    class Meta:
        model = Note
        fields = ['title', 'note_text', 'images']
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['images'].widget.attrs.update({'multiple': True})

覆盖form_valid方法以处理CreateNoteView中的多个图像

class CreateNoteView(CreateView):
    model = Note
    template_name = 'notes/add_note.html'
    form_class = AddNewNote

    def get_success_url(self):
        return reverse('show', kwargs={'pk' : self.object.pk})

    def form_valid(self, form):
        form.instance.add_date = timezone.now()
        form.instance.user = self.request.user
        self.object = form.save(commit=False)
        self.object.save()

        images = form.cleaned_data['images']
        for image in images:
            self.object.images.add(image)

        return super(CreateNoteView, self).form_valid(form)
t3irkdon

t3irkdon2#

尝试修改您的ImageField

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

提交表单时,选定的图像将作为文件列表提供。

6gpjuf90

6gpjuf903#

使用slugify为每个映像生成一个唯一的文件名以删除任何特殊字符和空格。然后,创建一个Image示例并使用ContentFile将上载的映像保存到该示例中,然后使用images.add()方法将Image示例添加到Note示例中

from django.core.files.base import ContentFile
from django.utils.text import slugify

class CreateNoteView(CreateView):
    model = Note
    template_name = 'your/note_link.html'
    form_class = AddNewNote

    def get_success_url(self):
        return reverse('show', kwargs={'pk' : self.object.pk})

    def form_valid(self, form):
        form.instance.add_date = timezone.now()
        form.instance.user = self.request.user
        self.object = form.save(commit=False)
        self.object.save()

        images = form.cleaned_data['images']
        for image in images:
            # Generate a unique filename for the image
            filename = slugify(image.name)
            # Create an Image instance and add it to the Note
            img_instance = Image.objects.create()
            img_instance.image.save(filename, ContentFile(image.read()))
            self.object.images.add(img_instance)

        return super().form_valid(form)

相关问题