Сохранять экземпляр файлов при наличии ошибки проверки на пост - PullRequest
0 голосов
/ 02 декабря 2018

У меня возникли некоторые проблемы с экземпляром этих файлов галереи и другими в моем проекте.Когда у меня возникают ошибки проверки, загруженные файлы исчезают.В этом случае я хотел заставить пользователя ввести по крайней мере 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...