Django formset UpdateView 不允许我上传文件
Django formset UpdateView won't let me upload files
我正在尝试创建一个包含多个内联表单集的 UpdateView 视图。它几乎可以正常工作,因为我可以添加或删除文件和图像,但由于某种原因它不接受任何 file/image。例如,如果我在出版物中添加第二个文件并上传文件,它将 return 一个 form_invalid 函数声明该字段在 FileField 旁边是必需的。图像也是如此——我无法添加任何新图像,或者我什至无法将任何图像更改为另一个文件,因为它会说该字段是必需的。除此之外,我可以更改所有的 Publication 字段,我还可以更改文件的标题、描述和版本,它会正确保存,但是当我添加一个新的 File/Image 或只是更改它使用的文件时,它不会做任何事情,它只会 return 一个无效的表单函数。
models.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')
forms.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">
我正在尝试创建一个包含多个内联表单集的 UpdateView 视图。它几乎可以正常工作,因为我可以添加或删除文件和图像,但由于某种原因它不接受任何 file/image。例如,如果我在出版物中添加第二个文件并上传文件,它将 return 一个 form_invalid 函数声明该字段在 FileField 旁边是必需的。图像也是如此——我无法添加任何新图像,或者我什至无法将任何图像更改为另一个文件,因为它会说该字段是必需的。除此之外,我可以更改所有的 Publication 字段,我还可以更改文件的标题、描述和版本,它会正确保存,但是当我添加一个新的 File/Image 或只是更改它使用的文件时,它不会做任何事情,它只会 return 一个无效的表单函数。
models.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')
forms.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">