具有IntegrityError异常的Django表单

时间:2018-11-22 14:04:56

标签: python django exception django-crispy-forms

我想得到您的帮助,以便在我的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()更改值,我也必须更改此表单。

0 个答案:

没有答案