我在 django 中有一个项目,负责创建带有可选添加图像的笔记。现在我可以添加最多一张图片的注释。我想允许用户添加任意数量的图像,但我不知道如何添加。我尝试在模型字段中使用 ArrayField 但它没有用。我想这样:当用户单击“添加图像”并且资源管理器出现时,他可以选择多个图像。然后将这些图像保存到一个模型实例中。例如,如果 img 字段将是数据库中的 ArrayField 将是: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 %}
尝试修改你的
ImageField
,
images = forms.ImageField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
提交表格后,所选图像将作为文件列表提供。
要将多个图像上传到单个
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
以允许用户选择多个图像
class AddNewNote(forms.ModelForm):
images = forms.ModelMultipleChoiceField(queryset=Image.objects.all(), widget=forms.ClearableFileMultipleInput(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)