Skip to main content
 首页 » 编程设计

python之Django formset UpdateView 不允许我上传文件

2024年08月20日32飞鱼

我正在尝试创建一个包含多个内联表单集的 UpdateView View 。它几乎可以正常工作,因为我可以添加或删除文件和图像,但由于某种原因它不接受任何文件/图像。例如,如果我在 Publication 中添加第二个文件并上传文件,它将返回一个 form_invalid 函数,指出 FileField 旁边的 This field is required。图像也是如此——我无法添加任何新图像,或者我什至无法将任何图像更改为另一个文件,因为它会说该字段是必需的。除此之外,我可以更改所有的 Publication 字段,我还可以更改文件的标题、描述和版本,它会正确保存,但是当我添加一个新的文件/图像或只是更改它使用的文件时,它不会什么都不做,它只会返回一个无效的表单函数。

模型.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') 

表单.py

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) 

views.py

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">