У меня возникли некоторые проблемы с экземпляром этих файлов галереи и другими в моем проекте.Когда у меня возникают ошибки проверки, загруженные файлы исчезают.В этом случае я хотел заставить пользователя ввести по крайней мере 3 изображения в галерею, но если он выбрал только одно и отправил форму, после POST
изображение появится там, но если он только заполнит остальные инажмите отправить, он скажет, что он не заполнил первый, который отправил в прошлый раз, потому что он только показывал, но по какой-то причине не отправил этот экземпляр в форму ...
Цель состоит в том, чтобы сохранить загруженные изображения в памяти, даже если пользователь снова и снова нажимает кнопку сохранения с ошибками, чтобы он мог заполнить только оставшиеся.
attachments.form.html
<div class="form-group">
<div class="col-sm-3 control-label">
<label class="">Gallery</label>
<br><br>
<small>Add photos to your project</small>
</div>
<div class="col-sm-9">
<div class="row">
{{ gallery.management_form }}
{% for form_gallery in gallery %}
<div class="col-lg-10 gallery-formset">
<p class="file-description">
{% if form_gallery.file.value %}
{% if gallery.non_form_errors %}
<span class="filename">
<a class="text" href="#">{{ form_gallery.post_file_name }}</a>
<span class="btn-delete glyphicon glyphicon-remove"></span>
</span>
{% else %}
<img width="150" class="media" src="/media/{{ form_gallery.file.value }}">
{% endif %}
{% else %}
<input type="file" class="hide" name="{{ form_gallery.file.html_name }}" value="{% if request.method == 'POST' %}{{ form_gallery.post_file }}{% else %}{{ form_gallery.file.value|default_if_none:'' }}{% endif %}" id="{{ form_gallery.file.html_name }}">
<label class="btn btn-primary btn-rounded btn-add" for="{{ form_gallery.file.html_name }}">ADD FILE</label>
{% endif %}
<small class="help-block">{{ form_gallery.file.errors }}</small>
</p>
</div>
{% endfor %}
<small class="help-block">{{ gallery.non_form_errors }}</small>
</div>
</div>
forms.py
class ProjectAttachmentForm(forms.ModelForm):
project = None
class Meta:
model = ProjectAttachment
exclude = ('project',)
def save(self, commit=True):
attachment = super(ProjectAttachmentForm, self).save(commit=False)
attachment.project = self.project
if commit:
attachment.save()
return attachment
class AttachmentFilesForm(forms.ModelForm):
file = forms.FileField(required=False, validators=[file_size_upload_limit])
original_name = forms.CharField(required=False)
class Meta:
model = Attachments
fields = ['original_name']
class AttachmentFilesBaseFormset(BaseFormSet):
parent = None
category = None
def __init__(self, *args, **kwargs):
self.category = kwargs.pop('category', None)
if self.category:
kwargs['prefix'] = self.category
self.parent = kwargs.pop('parent', None)
if self.parent and self.category:
kwargs['initial'] = [model_to_dict(attachment) for attachment in Attachments.objects.filter(attachment=self.parent, category=self.category)]
super(AttachmentFilesBaseFormset, self).__init__(*args, **kwargs)
def save(self):
if any(self.errors):
return
to_create = []
to_delete = []
for form in self.forms:
if form.has_changed():
file = form.cleaned_data.get('file', None)
if file:
attachment = Attachments(attachment=self.parent, original_name=file.name, category=self.category)
filename = random_filename(file, file.name)
attachment.file.save(name=filename, content=file, save=False)
to_create.append(attachment)
self.parent.attachments_set.filter(category=self.category).delete()
Attachments.objects.bulk_create(to_create)
AttachmentGalleryFormset = formset_factory(AttachmentFilesForm, formset=AttachmentFilesBaseFormset, extra=3, max_num=3, min_num=3, validate_min=True)
views.py - post
project = get_object_or_404(ProjectData, pk=project)
attachments = ProjectAttachment.objects.filter(project=project).first() if project else None
form = self.form_class(request.POST, request.FILES, instance=attachments)
form.project = project
gallery_form = AttachmentGalleryFormset(request.POST, request.FILES, category='gallery', parent=attachments)
if form.is_valid() and gallery_form.is_valid():
with transaction.atomic():
attachments = form.save()
gallery_form.parent = attachments
gallery_form.save()
messages.success(request, 'Success')
return HttpResponseRedirect(request.path)
else:
messages.error(request, 'Failed')
i = 0
for gallery in gallery_form:
gallery.post_file_name = gallery.files.get('gallery-' + str(i) + '-file')
if gallery.post_file_name:
gallery.post_file = gallery.post_file_name.read()
i = i + 1
return render(request, self.template_name, {'form': form 'gallery': gallery_form, 'form_template': "components/attachments.form.html"})
models.py
class ProjectAttachment(models.Model):
project = models.OneToOneField(ProjectData, on_delete=models.CASCADE)
class Attachments(models.Model):
attachment = models.ForeignKey(ProjectAttachment, on_delete=models.CASCADE)
original_name = models.CharField(max_length=255)
file = models.FileField(upload_to=random_filename, unique=True)
category = models.CharField(max_length=50)