我想得到您的帮助,以便在我的except IntegrityError
中使用formset
。
我有我的模型文件:
class Document(models.Model):
code = models.CharField(max_length=25, verbose_name=_('code'), unique=True, null=False, blank=False, default='')
language = models.CharField(max_length=2, verbose_name=_('language'), choices=LANGUAGE_CHOICES)
format = models.CharField(max_length=10, verbose_name=_('format'), choices=FORMAT_CHOICES)
title = models.CharField(max_length=512, verbose_name=_('title'))
publication = models.ForeignKey(Publication, verbose_name=_('publication title'), related_name='documents')
upload = models.FileField(upload_to='media/', validators=[validate_file_extension], verbose_name=_('document file'), )
class Meta:
verbose_name = _('document')
verbose_name_plural = _('documents')
def save(self, *args, **kwargs):
self.code = f"{self.publication.pub_id}-{self.language.upper()}-{self.format.upper()}"
super(Document, self).save(*args, **kwargs)
def __str__(self):
return f"{self.title}"
如您所见,code field
取决于用户使用相关表单填写的数据。
每个code
字段都必须是唯一的。
我有一个表单集:
class DocumentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(DocumentForm, self).__init__(*args, **kwargs)
for key in self.fields:
self.fields[key].required = True
class Meta:
model = Document
fields = ['publication', 'language', 'format', 'title', 'upload']
DocumentFormSet = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1, max_num=4, can_delete=True)
如果用户用相同的值填写表单集中的不同表单,则我有一个except IntegrityError
的views.py文件。因为它将创建相同的code
ang用户,所以会出现错误。
class PublicationCreateView(CreateView):
model = Publication
template_name = 'publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
document_queryset = Document.objects.all()
context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None,
prefix='doc', queryset=document_queryset)
return context
def form_valid(self, form):
try:
context = self.get_context_data()
formsets = context['DocumentFormSets']
if form.is_valid():
self.object = form.save()
if formsets.is_valid():
formsets.instance = self.object
formsets.save(commit=False)
for element in formsets:
element.save(commit=False)
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
except IntegrityError:
messages.error(self.request, _(f"Issue with documents"))
return render(self.request, self.template_name)
您可以找到我的模板,但是我不知道这是否有必要!
<form method="post" action="" enctype="multipart/form-data" novalidate>
{% csrf_token %}
{# {{ form.management_form }}#}
<fieldset>
<legend class="title"><span class="name">{% trans 'Publication form' %}</span></legend>
<div class="row">
<div class="col-xs-6">
{{ form.category|as_crispy_field }}
</div>
<div class="col-xs-6">
{{ form.pub_id|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-xs-6">
{{ form.title|as_crispy_field }}
</div>
<div class="col-xs-6">
{{ form.cover|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-xs-12">
{{ form.description|as_crispy_field }}
</div>
</div>
</fieldset>
<fieldset>
<legend class="title"><span class="name">{% trans 'Document form' %}</span></legend>
{{ DocumentFormSets.management_form }}
<div id="form_set">
{% for form in DocumentFormSets.forms %}
<div class='formset-document'>
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
{{ form.title|as_crispy_field }}
</div>
<div class="col-xs-3">
{{ form.language|as_crispy_field }}
</div>
<div class="col-xs-3">
{{ form.format|as_crispy_field }}
</div>
<div class="col-xs-3">
{{ form.upload|as_crispy_field }}
</div>
</div>
</table>
</div>
{% endfor %}
</div>
<br>
<input type="button" class="btn btn-default" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
{{ DocumentFormSets.empty_form.title|as_crispy_field }}
</div>
<div class="col-xs-3">
{{ DocumentFormSets.empty_form.language|as_crispy_field }}
</div>
<div class="col-xs-3">
{{ DocumentFormSets.empty_form.format|as_crispy_field }}
</div>
<div class="col-xs-3">
{{ DocumentFormSets.empty_form.upload|as_crispy_field }}
</div>
</div>
</table>
</div>
</fieldset>
<br>
<input type="submit" class="btn btn-default" value="{% trans 'Save' %}"/>
<a href="{{ request.META.HTTP_REFERER }}" class="btn btn-default">{% trans 'Cancel' %}</a>
</form>
我遇到了这个问题:
Exception Value: |as_crispy_field got passed an invalid or inexistent field
因为:
上述异常(重复的键值违反了唯一约束 “ freepub_document_code_key”详细信息:密钥(代码)=(PUBSD-8119-FR-PDF) 已经存在。 )是以下异常的直接原因: Formsets.save()
编辑:
我尝试过:
try:
context = self.get_context_data()
formsets = context['DocumentFormSets']
if form.is_valid():
self.object = form.save()
if formsets.is_valid():
formsets.instance = self.object
formsets.save(commit=False)
for element in formsets:
element.save(commit=False)
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
except IntegrityError:
messages.error(self.request, _(f"Issue with documents"))
return super(PublicationCreateView, self).form_invalid(form)
我似乎可以工作,但是也许我不必使用第一个表单,因为他也具有唯一的值,并且如果我根据form_invalid()更改值,我也必须更改此表单。