如何上传多张带标志的图片到Django

siv3szwd  于 2022-12-30  发布在  Go
关注(0)|答案(1)|浏览(128)

我正在建立一个网页,博客作者可以在这里写内容和上传图片。使用图片字段,我允许作者上传多张图片,并使用一些Javascript逻辑,我在上传前显示图片。在每张图片下,我有一个复选框,指示这是否是帖子的主图片(例如,第一张显示在幻灯片中,并用作帖子本身的缩略图)。
在这个页面上,我展示了两个表单,它们都有一个共享的提交按钮,而且运行良好。
我的问题开始时,我试图保存图像,也表明它是否是主要的一个。
我的图片模型有很多有用的方法,比如Django管理员的thumbnail属性和一个保存方法,在编辑/添加一个新的main_image之前,这个方法会将所有的图片设置为false。由于我的实验,我不得不加入一个commit参数逻辑。请忽略它。这个模型包括3个字段:图像、主标志和指向帖子的外键,如下所示:

class PostImages(models.Model):
    """
    Post images for the blog app.
    """
    image = models.ImageField(
        verbose_name=_("Изображение"),
        upload_to='blog/images/',
        blank=False,
        null=False,
        default='blog/images/default.jpg'
    )
    post = models.ForeignKey(
        to=Post,
        on_delete=models.CASCADE,
        verbose_name=_('Статия')
    )
    main_image = models.BooleanField(
        default=False,
        verbose_name=_('Основно изображение')
    )

    class Meta:
        verbose_name = _('Изображение')
        verbose_name_plural = _('Изображения')
        permissions = [
            ('can_manage_post_image', _('Може да управлява изображенията на публикациите')),
            ('can_add_post_image', _('Може да добавя изображения към публикациите')),
        ]

    def __str__(self):
        return f"{self.post.title} - {self.image}"

    def get_absolute_url(self):
        return f"/blog/post/image/{self.id}"

    def get_edit_url(self):
        return f"/blog/post/image/{self.id}/edit"

    def get_delete_url(self):
        return f"/blog/post/image/{self.id}/delete"

    def get_image(self):
        return mark_safe(f'<img src="{self.image.url}" width="100" height="100" />')

    def get_image_url(self):
        return self.image.url

    @property
    def thumbnail_preview(self):
        if self.image:
            return mark_safe('<img src="{}" width="400" height="auto" />'.format(self.image.url))
        return ''

    def save(self, *args, **kwargs):
        if self.main_image and kwargs.get("commit", True):
            PostImages.objects.filter(post=self.post).update(main_image=False)
        kwargs.pop("commit", None)
        super().save(*args, **kwargs)

我还使用了一个模型表单。在模型表单中,我不请求帖子,因为它还没有创建。我的想法是在保存阶段填写帖子,遵循以下过程:
1.保存帖子
1.保存图像对我来说这是一个合乎逻辑的举动,但知道到目前为止花了我多少时间-〉可能不是最好的举动。

class PostImagesForm(forms.ModelForm):
    """
    Form for uploading images for posts.
    """
    image = forms.ImageField(
        label='Снимка',
        widget=forms.ClearableFileInput(
            attrs={
                'class': 'form-control',
                'multiple': True,
            }
        )
    )

    main_image = forms.BooleanField(
        label='Основна снимка',
        required=False,
        widget=forms.CheckboxInput(
            # attrs={
            #     'class': 'form-control',
            # }
        )
    )

    class Meta:
        model = PostImages
        fields = ['image', 'main_image']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['image'].required = False

    def save(self, commit=True):
        """
        Save the form and return the created or edited post.
        """
        post_image = super().save(commit=False)
        post_image.save(commit=commit)
        return post_image

    def clean(self):
        """
        Clean the form and return the cleaned data.
        """
        cleaned_data = super().clean()
        return cleaned_data

到目前为止,一切都很好,我想。
所以问题是这样的:

  • 如何告诉Django我正在上传一对字段(文件和复选框)?
  • 如何将post示例传递给图像?
  • 为什么我的请求文件为空?
  • 我应该如何分组图像-复选框对?它是在html里面的东西吗?

我尝试使用表单本身,但它缺少post示例。
我试图遍历这些文件,但它们是空的。
我尝试遍历表单字段,但没有看到所有上载的文件。

piv4azn7

piv4azn71#

如果有人需要这个:
我发现了多个问题,我认为分享这些问题可能会有用。
1.我在一个提交按钮下使用多个表单。在某个时候我扮演了自己,并从我的表单标签中删除了enctype="multipart/form-data"。(哎呀)
1.我的javascript有一个奇怪的行为,因为它在我的复选框标识符中将图片作为"data:sjdfhsdkjbfksd",所以又是一个新手错误,当我开始将console.log()添加到任何东西时,我发现了它。
1.如果你和我一样(主要语言是Python,JS是偶然知道的),记住-在浏览器中有一个很棒的JS调试器,在sources下。

  1. JS作用域很奇怪,和Python中的作用域不一样。在使用调试器时,你会发现循环在做事情和调用事件函数时,总是会做事件函数之外的所有事情,然后转移到你的事件函数中。你可以通过在var语句中重新赋值来传递东西,但是要准备好被一个JS家伙尖叫。

相关问题