Django:未提交文件。检查表单上的编码类型

问题描述 投票:0回答:1

我正在尝试在我的 Django 项目中实现多重上传。在执行与此问题的答案类似的操作后,我在提交时收到

No file was submitted. Check the encoding type on the form.
表单错误(self.errors ==
<ul class="errorlist"><li>image<ul class="errorlist"><li>No file was submitted. Check the encoding type on the form.</li></ul></li></ul>
)。可能是什么问题呢?你能帮我一下吗?

我的

models.py:

from PIL import Image as I

class Galery(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    description = models.TextField(blank=True)

    def __str__(self):
        return self.user.userprofile.username + " - " + self.description


class Image(models.Model):
    galery = models.ForeignKey(Galery, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='photos', blank=True, null=True)

    def save(self, *args, **kwargs):
        img = I.open(self.image.name)
        img.resize(size=(300, 300))
        img.save(self.image.name)
        return super(Image, self).save(*args, **kwargs)

我的

forms.py:

class CustomFileInput(forms.ClearableFileInput):
    allow_multiple_selected = True


class AddPhotoForm(forms.ModelForm):
    description = forms.CharField(widget=forms.Textarea(), required=False)

    class Meta:
        model = Galery
        fields = ['description']

    def save(self, commit=True):
        if commit:
            post = Galery.objects.create(
                user=self.instance,
                description=self.cleaned_data['description']
            )

            return post


class AddImagesForm(AddPhotoForm):
    image = forms.FileField(widget=CustomFileInput(attrs={'multiple': True}), required=True)

    class Meta(AddPhotoForm.Meta):
        fields = AddPhotoForm.Meta.fields + ['image']

我的

views.py:

class AddPhotoView(CreateView):
    template_name = 'add-photo.html'
    form_class = AddImagesForm
    success_url = 'my-space'

    def get(self, request, *args, **kwargs):
        form = self.form_class()
        return render(request, self.template_name, context={'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST,
                               request.FILES,
                               instance=request.user)
        photos = request.FILES.getlist('image')
        if photos:
            if form.is_valid():
                galery = form.save()
                for photo in photos:
                    Image.objects.create(galery=galery, image=photo)

                return redirect(self.success_url)
        else:
            messages.error(request, message='Upload at least one photo!')
        return render(request, self.template_name, context={'form': form})

我的

add-photo.html

{% load widget_tweaks %}

            <form method="post" enctype="multipart/form-data">
              {% csrf_token %}
                <div class="d-flex justify-content-center">
                    {% render_field form.image name="image" %}
                </div><br>
                <div class="d-flex justify-content-center">
                    <ul class="list-group" id="list">
                    </ul>
                </div><br>
                <div class="d-flex justify-content-center">
                    <b>Add description: </b>
                </div><br>
                <div class="d-flex justify-content-center">
                    {% render_field form.description class="form-control" style="width: 300px;" placeholder="Write description here..." %}
                </div><br>
                <div class="d-flex justify-content-center">
                    <button style="width: 200px;" class="btn btn-primary" type="submit">Post</button>
                </div>
            </form>

我将非常感谢任何可以帮助我的人。谢谢!

django django-forms django-templates
1个回答
0
投票

用户逻辑的建模似乎有点奇怪。您似乎使用了

CustomUser
,我认为这是用户模型,但是如果您制作自定义用户模型,那么拥有单独的
UserProfile
模型没有多大意义:创建自定义用户模型通常已完成 完全以避免制作额外的模型。

但无论如何,我认为你正在实现方式太多的样板代码。因此,例如

AddPhotoForm
无法与
commit=False
一起使用,并且不能再用于 编辑
Galery

主要问题可能是 Django 的内置

FileField
无法处理多个文件,或者至少默认情况下不能。我们必须创建一个表单字段,以便在上传多个表单字段时对其进行验证,例如使用文档中指定的表单字段[Django-doc]

class MultipleFileInput(forms.ClearableFileInput): allow_multiple_selected = True class MultipleFileField(forms.FileField): def __init__(self, *args, **kwargs): kwargs.setdefault("widget", MultipleFileInput()) super().__init__(*args, **kwargs) def clean(self, data, initial=None): single_file_clean = super().clean if isinstance(data, (list, tuple)): result = [single_file_clean(d, initial) for d in data] else: result = single_file_clean(data, initial) return result

表单字段的新

clean

 方法是必要的,因为我们将处理 
多个 项目。

现在我们可以制作一个

Galery

 表格:

class AddPhotoForm(forms.ModelForm): image = MultipleFileField() class Meta: model = Galery fields = ['description'] def save(self, commit=True): result = super().save(commit=commit) if commit: for image in self.cleaned_data['image']: Image(galery=result, image=image).save() return result
现在我们可以让 

CreateView

 完成它的工作:

from django.contrib.auth.mixins import LoginRequiredMixin class AddPhotoView(LoginRequiredMixin, CreateView): template_name = 'add-photo.html' form_class = AddImagesForm success_url = 'my-space' def form_valid(self, form): form.instance.user = self.request.user return super().form_valid(form) def form_invalid(self, form): messages.error(self.request, message='Upload at least one photo!') return super().form_invalid(form)
    
© www.soinside.com 2019 - 2024. All rights reserved.