Python Django formset UpdateView赢得';我不能上传文件

Python Django formset UpdateView赢得';我不能上传文件,python,django,django-forms,django-class-based-views,formset,Python,Django,Django Forms,Django Class Based Views,Formset,我正在尝试使用多个内联表单集创建UpdateView视图。它几乎可以正常工作,因为我可以添加或删除文件和图像,但由于某些原因,它不会接受任何文件/图像。例如,如果我在出版物中添加了第二个文件并上载了一个文件,它将返回一个form_invalid函数,说明FileField旁边需要此字段。图像也是一样——我不能添加任何新图像,或者我甚至不能将任何图像更改为另一个文件,因为它会说这个字段是必需的。除此之外,我可以更改所有的发布字段,也可以更改文件的标题、描述和版本,这样可以正确保存,但当我添加新文件

我正在尝试使用多个内联表单集创建UpdateView视图。它几乎可以正常工作,因为我可以添加或删除文件和图像,但由于某些原因,它不会接受任何文件/图像。例如,如果我在出版物中添加了第二个文件并上载了一个文件,它将返回一个form_invalid函数,说明FileField旁边需要此字段。图像也是一样——我不能添加任何新图像,或者我甚至不能将任何图像更改为另一个文件,因为它会说这个字段是必需的。除此之外,我可以更改所有的发布字段,也可以更改文件的标题、描述和版本,这样可以正确保存,但当我添加新文件/图像或只是更改它使用的文件时,它不会做任何事情,只会返回无效的表单函数

型号.py

class Publication(models.Model):
    title = models.CharField('Tytul', max_length=100)
    author = models.ForeignKey(User, verbose_name=('Author'), blank=True, default=0)
    pub_date = models.DateTimeField('Data publikacji', default=datetime.now)
    mod_date = models.DateTimeField('Data ostatniej modyfikacji', default=datetime.now)
    description = models.CharField('Opis', max_length=450)
    slug = models.SlugField(max_length=40, unique=True)
    category = models.ForeignKey(Category, verbose_name=('Kategoria'), default=0, related_name='publication')
    video = EmbedVideoField(blank=True)

class File(models.Model):
    title = models.CharField('Tytul', max_length=100)
    version = models.CharField(verbose_name=u"Wersja", max_length=100)
    author = models.ForeignKey(User, verbose_name=('Author'), blank=True, default=0)
    pub_date = models.DateTimeField('Data publikacji', default=datetime.now)
    mod_date = models.DateTimeField('Data ostatniej modyfikacji', default=datetime.now)
    description = models.CharField('Opis', max_length=450)
    downloads = models.IntegerField(default=0)
    physicalfile = models.FileField('Wrzuc plik', upload_to=randomfilenames, validators=[validate_extension])
    publicationfk = models.ForeignKey(Publication,on_delete=models.CASCADE, related_name='files')


class Image(models.Model):
    publication = models.ForeignKey(Publication, related_name='images')
    image = VersatileImageField('Wrzuc obrazek')
class FileForm(forms.ModelForm):
    class Meta:
        model = File
        fields = ['title', 'version', 'description', 'physicalfile',]

class ImgForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['image',]

class PublicationForm(forms.ModelForm):
    class Meta:
        model = Publication
        fields = ['title', 'description', 'slug', 'category',]

fileformset = inlineformset_factory(Publication, File, form=FileForm, exclude=[],can_delete=True, extra=1)
imageformset = inlineformset_factory(Publication, Image, form=ImgForm, can_delete=True, exclude=[], extra=1)
class PublicationEdit(UpdateView):
    model = Publication
    form_class = PublicationForm
    template_name = 'mods/pubedit.html'

    def get_success_url(self):
        self.success_url = reverse('mods:publicationview', args=(self.object.id,))
        return self.success_url

    def get_context_data(self, **kwargs):
        context = super(PublicationEdit, self).get_context_data(**kwargs)
        if self.request.POST:
            context['pubform'] = PublicationForm(self.request.POST, instance=self.object)
            context['fileform'] = fileformset(self.request.POST, self.request.FILES, instance=self.object)
            context['imgform'] = imageformset(self.request.POST, self.request.FILES, instance=self.object)
        else:
            context['pubform'] = PublicationForm(instance=self.object)
            context['fileform'] = fileformset(instance=self.object)
            context['imgform'] = imageformset(instance=self.object)
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        pubform = self.get_form(form_class)
        fileform = fileformset(self.request.POST, self.request.FILES, instance=self.object)
        imgform = imageformset(self.request.POST, self.request.FILES, instance=self.object)

        if (pubform.is_valid() and fileform.is_valid() and imgform.is_valid()):
            return self.form_valid(pubform, fileform, imgform)
        else:
            return self.form_invalid(pubform, fileform, imgform)


    def form_valid(self, pubform, fileform, imgform):
        self.object = pubform.save()
        fileform.instance = self.object
        fileform.save()
        imgform.instance = self.object
        imgform.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, pubform, fileform, imgform):
        return self.render_to_response(self.get_context_data(pubform=pubform,
                                  fileform=fileform,
                                  imgform=imgform))
forms.py

class Publication(models.Model):
    title = models.CharField('Tytul', max_length=100)
    author = models.ForeignKey(User, verbose_name=('Author'), blank=True, default=0)
    pub_date = models.DateTimeField('Data publikacji', default=datetime.now)
    mod_date = models.DateTimeField('Data ostatniej modyfikacji', default=datetime.now)
    description = models.CharField('Opis', max_length=450)
    slug = models.SlugField(max_length=40, unique=True)
    category = models.ForeignKey(Category, verbose_name=('Kategoria'), default=0, related_name='publication')
    video = EmbedVideoField(blank=True)

class File(models.Model):
    title = models.CharField('Tytul', max_length=100)
    version = models.CharField(verbose_name=u"Wersja", max_length=100)
    author = models.ForeignKey(User, verbose_name=('Author'), blank=True, default=0)
    pub_date = models.DateTimeField('Data publikacji', default=datetime.now)
    mod_date = models.DateTimeField('Data ostatniej modyfikacji', default=datetime.now)
    description = models.CharField('Opis', max_length=450)
    downloads = models.IntegerField(default=0)
    physicalfile = models.FileField('Wrzuc plik', upload_to=randomfilenames, validators=[validate_extension])
    publicationfk = models.ForeignKey(Publication,on_delete=models.CASCADE, related_name='files')


class Image(models.Model):
    publication = models.ForeignKey(Publication, related_name='images')
    image = VersatileImageField('Wrzuc obrazek')
class FileForm(forms.ModelForm):
    class Meta:
        model = File
        fields = ['title', 'version', 'description', 'physicalfile',]

class ImgForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['image',]

class PublicationForm(forms.ModelForm):
    class Meta:
        model = Publication
        fields = ['title', 'description', 'slug', 'category',]

fileformset = inlineformset_factory(Publication, File, form=FileForm, exclude=[],can_delete=True, extra=1)
imageformset = inlineformset_factory(Publication, Image, form=ImgForm, can_delete=True, exclude=[], extra=1)
class PublicationEdit(UpdateView):
    model = Publication
    form_class = PublicationForm
    template_name = 'mods/pubedit.html'

    def get_success_url(self):
        self.success_url = reverse('mods:publicationview', args=(self.object.id,))
        return self.success_url

    def get_context_data(self, **kwargs):
        context = super(PublicationEdit, self).get_context_data(**kwargs)
        if self.request.POST:
            context['pubform'] = PublicationForm(self.request.POST, instance=self.object)
            context['fileform'] = fileformset(self.request.POST, self.request.FILES, instance=self.object)
            context['imgform'] = imageformset(self.request.POST, self.request.FILES, instance=self.object)
        else:
            context['pubform'] = PublicationForm(instance=self.object)
            context['fileform'] = fileformset(instance=self.object)
            context['imgform'] = imageformset(instance=self.object)
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        pubform = self.get_form(form_class)
        fileform = fileformset(self.request.POST, self.request.FILES, instance=self.object)
        imgform = imageformset(self.request.POST, self.request.FILES, instance=self.object)

        if (pubform.is_valid() and fileform.is_valid() and imgform.is_valid()):
            return self.form_valid(pubform, fileform, imgform)
        else:
            return self.form_invalid(pubform, fileform, imgform)


    def form_valid(self, pubform, fileform, imgform):
        self.object = pubform.save()
        fileform.instance = self.object
        fileform.save()
        imgform.instance = self.object
        imgform.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, pubform, fileform, imgform):
        return self.render_to_response(self.get_context_data(pubform=pubform,
                                  fileform=fileform,
                                  imgform=imgform))
视图.py

class Publication(models.Model):
    title = models.CharField('Tytul', max_length=100)
    author = models.ForeignKey(User, verbose_name=('Author'), blank=True, default=0)
    pub_date = models.DateTimeField('Data publikacji', default=datetime.now)
    mod_date = models.DateTimeField('Data ostatniej modyfikacji', default=datetime.now)
    description = models.CharField('Opis', max_length=450)
    slug = models.SlugField(max_length=40, unique=True)
    category = models.ForeignKey(Category, verbose_name=('Kategoria'), default=0, related_name='publication')
    video = EmbedVideoField(blank=True)

class File(models.Model):
    title = models.CharField('Tytul', max_length=100)
    version = models.CharField(verbose_name=u"Wersja", max_length=100)
    author = models.ForeignKey(User, verbose_name=('Author'), blank=True, default=0)
    pub_date = models.DateTimeField('Data publikacji', default=datetime.now)
    mod_date = models.DateTimeField('Data ostatniej modyfikacji', default=datetime.now)
    description = models.CharField('Opis', max_length=450)
    downloads = models.IntegerField(default=0)
    physicalfile = models.FileField('Wrzuc plik', upload_to=randomfilenames, validators=[validate_extension])
    publicationfk = models.ForeignKey(Publication,on_delete=models.CASCADE, related_name='files')


class Image(models.Model):
    publication = models.ForeignKey(Publication, related_name='images')
    image = VersatileImageField('Wrzuc obrazek')
class FileForm(forms.ModelForm):
    class Meta:
        model = File
        fields = ['title', 'version', 'description', 'physicalfile',]

class ImgForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ['image',]

class PublicationForm(forms.ModelForm):
    class Meta:
        model = Publication
        fields = ['title', 'description', 'slug', 'category',]

fileformset = inlineformset_factory(Publication, File, form=FileForm, exclude=[],can_delete=True, extra=1)
imageformset = inlineformset_factory(Publication, Image, form=ImgForm, can_delete=True, exclude=[], extra=1)
class PublicationEdit(UpdateView):
    model = Publication
    form_class = PublicationForm
    template_name = 'mods/pubedit.html'

    def get_success_url(self):
        self.success_url = reverse('mods:publicationview', args=(self.object.id,))
        return self.success_url

    def get_context_data(self, **kwargs):
        context = super(PublicationEdit, self).get_context_data(**kwargs)
        if self.request.POST:
            context['pubform'] = PublicationForm(self.request.POST, instance=self.object)
            context['fileform'] = fileformset(self.request.POST, self.request.FILES, instance=self.object)
            context['imgform'] = imageformset(self.request.POST, self.request.FILES, instance=self.object)
        else:
            context['pubform'] = PublicationForm(instance=self.object)
            context['fileform'] = fileformset(instance=self.object)
            context['imgform'] = imageformset(instance=self.object)
        return context

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        pubform = self.get_form(form_class)
        fileform = fileformset(self.request.POST, self.request.FILES, instance=self.object)
        imgform = imageformset(self.request.POST, self.request.FILES, instance=self.object)

        if (pubform.is_valid() and fileform.is_valid() and imgform.is_valid()):
            return self.form_valid(pubform, fileform, imgform)
        else:
            return self.form_invalid(pubform, fileform, imgform)


    def form_valid(self, pubform, fileform, imgform):
        self.object = pubform.save()
        fileform.instance = self.object
        fileform.save()
        imgform.instance = self.object
        imgform.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, pubform, fileform, imgform):
        return self.render_to_response(self.get_context_data(pubform=pubform,
                                  fileform=fileform,
                                  imgform=imgform))

最可能的原因是没有设置表单的enctype属性。 如果使用表单上载文件,则应设置
enctype
属性,如下所示:

<form method="post" enctype="multipart/form-data">


是否设置表单的enctype=“multipart/form data”?@neverwalkoner嗯,不,我没有。我完全忘了。非常感谢,我花了几个小时试图找出我的代码有什么问题,同时我忘记了这个基本的东西,它现在工作得很好。不客气。我发表了我的评论作为回答。