Django 多表单到一个视图:如何处理字段错误?

Django 多表单到一个视图:如何处理字段错误?,django,django-models,django-forms,django-views,Django,Django Models,Django Forms,Django Views,我有一个这样的模型: class PersonneTravel(models.Model): personne = models.ForeignKey(Personne, verbose_name=_(u'Person')) travel = models.TextField(null=True, blank=True, verbose_name=_(u'Travel')) date_start = models.DateTimeField(default=None, n

我有一个这样的模型:

class PersonneTravel(models.Model):
    personne = models.ForeignKey(Personne, verbose_name=_(u'Person'))
    travel = models.TextField(null=True, blank=True, verbose_name=_(u'Travel'))
    date_start = models.DateTimeField(default=None, null=True, blank=True,
                                      editable=True, verbose_name=_(u"Start"))
    date_end = models.DateTimeField(default=None, null=True, blank=True,
                                    editable=True, verbose_name=_(u"End"))
    comments = models.TextField(null=True, blank=True,
                                verbose_name=_(u'Comments'))
def get_context_data(self, **kwargs):
    context = super(IndexView, self).get_context_data(**kwargs)
    context['travels'] = []
    for ptf in PersonneTravel.objects.filter(
        personne__user=self.request.user,
    ):
        context['travels'].append({
            'obj': ptf,
            'form': PersonneTravelForm({
                'pk': ptf.pk,
                'travel': ptf.travel.value,
                'date_start': ptf.date_start,
                'date_end': ptf.date_end,
                'comments': ptf.comments,
            })
        })
我显示一个人所有旅行的列表。 我想做的是允许在线-编辑任何旅行,或将一个添加到一个视图中

我是这样做的:

  • 创建一个表单:
    class PersonneTravelForm
    包含所有字段
  • 创建视图
    类索引视图(LoginRequiredMixin,generic.FormView):
  • 重载
    get\u context\u data
    在这里我创建了如下所有表单:

    class PersonneTravel(models.Model):
        personne = models.ForeignKey(Personne, verbose_name=_(u'Person'))
        travel = models.TextField(null=True, blank=True, verbose_name=_(u'Travel'))
        date_start = models.DateTimeField(default=None, null=True, blank=True,
                                          editable=True, verbose_name=_(u"Start"))
        date_end = models.DateTimeField(default=None, null=True, blank=True,
                                        editable=True, verbose_name=_(u"End"))
        comments = models.TextField(null=True, blank=True,
                                    verbose_name=_(u'Comments'))
    
    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['travels'] = []
        for ptf in PersonneTravel.objects.filter(
            personne__user=self.request.user,
        ):
            context['travels'].append({
                'obj': ptf,
                'form': PersonneTravelForm({
                    'pk': ptf.pk,
                    'travel': ptf.travel.value,
                    'date_start': ptf.date_start,
                    'date_end': ptf.date_end,
                    'comments': ptf.comments,
                })
            })
    
  • 在此模板中,我创建了一个循环:

    {% for v in travels %}
        {% with v.form as form %}
            {% include "my_home/travels/travel_form.html" %}
        {% endwith %}{# form #}
    {% endfor %}
    
  • 在文件
    travel\u form.html
    中,我显示表单

  • 我为每个表单添加了一个带有“编辑”按钮的javascript,当用户点击它时,我
    slideDown()
    表单
  • 当用户单击“
    update
    ”更新一次旅行时,相应的表单将作为
    POST
    发送。在表单代码中,我已在表单
    def clean_XXXX(self):
    中创建了所有过滤器,所有字段都已正确“清理”
  • 在视图中,我分析了
    def form\u valid(self,form)
    中的字段:
    • 如果字段中有
      pk
      ,则用于更新或删除
      • 如果所有其他字段均为“无”,我将删除它们
      • 如果任何字段不是None,则我更新
    • 如果没有
      pk
      是为了添加新记录,我就添加一条
我最大的也是唯一的问题是出现错误时:如果我在检查表单时尝试添加错误,并且出现问题,我会这样做,例如:

def form_valid(self, form):
    fc = form.cleaned_data
    d_start = fc['date_start']
    d_end = fc['date_end']
    comments = fc.get('comments', None)

    if d_end and d_start:
        if d_end > datetime.datetime.now().date() > d_start:
            form.add_error('date_start', _(u"Can't start in the past..."))
            form.add_error('date_end', _(u"...and end in the future!"))
            return super(IndexView, self).form_invalid(form)

一切似乎都很好。。。除了错误字段总是进入“添加新的”空白表单,而不是好的“编辑”表单之外。您将如何处理此问题?

当您处理相同类型的表单列表时,您需要这样做。Formset为您提供了创建新记录以及删除和更新旧记录的内置功能。

您需要的是Django Formset@MuhammadTahir您应该将您的评论作为答案重新发布。@OlivierPons第一点:
generic.FormView
用于处理单个表单(
dango.fomr
),但是你有一个表格列表。此外,您没有在表单前面加前缀,因此您甚至无法知道哪些表单已提交。您当然可以解决这两个问题,但Django有一个完全适用于此用例的表单集。@MuhammadTahir,我可以请您回答下面的问题,以便我检查您的答案是否有效吗?“我已经走得太远了,无法用“干净的代码”打破一切,我没有时间”-嗯,您的电话,但根据经验,这总是会花费更多的时间尝试让丑陋的解决方案工作,然后在部署后调试它,而不是仅仅抛弃丑陋的代码,用干净的解决方案重新开始。。。