我正在建立一个网页,博客作者可以在这里写内容和上传图片。使用图片字段,我允许作者上传多张图片,并使用一些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示例。
我试图遍历这些文件,但它们是空的。
我尝试遍历表单字段,但没有看到所有上载的文件。
1条答案
按热度按时间piv4azn71#
如果有人需要这个:
我发现了多个问题,我认为分享这些问题可能会有用。
1.我在一个提交按钮下使用多个表单。在某个时候我扮演了自己,并从我的表单标签中删除了
enctype="multipart/form-data"
。(哎呀)1.我的javascript有一个奇怪的行为,因为它在我的复选框标识符中将图片作为
"data:sjdfhsdkjbfksd"
,所以又是一个新手错误,当我开始将console.log()
添加到任何东西时,我发现了它。1.如果你和我一样(主要语言是Python,JS是偶然知道的),记住-在浏览器中有一个很棒的JS调试器,在
sources
下。var
语句中重新赋值来传递东西,但是要准备好被一个JS家伙尖叫。