【问题标题】:Django: how to display form errors for each model object in a inline formsetDjango:如何显示内联表单集中每个模型对象的表单错误
【发布时间】:2012-03-15 05:49:38
【问题描述】:

我有一个作者模型和一个书籍模型。用户可以修改给定作者的所有书籍的属性。我希望能够显示每本书的错误,而不是将所有错误都列在顶部,我该怎么做?

模型

from django.db import models
from django.forms import ModelForm, Textarea
from django import forms

class Author(models.Model):
    fname = models.CharField(max_length=100)
    lname = models.CharField(max_length=100)
    def fullname(self):
        return '%s %s' % (self.fname, self.lname)
    fullname = property(fullname)
    def __unicode__(self):
        return self.fullname

class Books(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=50)
    publisher = models.CharField(max_length=50)
    edition = models.CharField(max_length=50)
    comment = models.TextField()
    def __unicode__(self):
         return self.title

查看

def author_books_edit(request, author_id):
    a = get_object_or_404(Author, pk=author_id)
    authorsbooks = a.books_set.all()
    bookformset = inlineformset_factory(Author, Books, can_delete=True, can_order=True, exclude=('company',), extra=1)
    formset = bookformset(instance=a)
    if request.method == "POST":
        formset = bookformset(request.POST, request.FILES, instance=a)
        if formset.is_valid():
            formset.save()
        else:
            form_errors = formset.errors
            return render_to_response('test/authors_books_edits.html', {'author': a, 'authorsbooks': authorsbooks, 'formset': formset, 'form_errors': form_errors}, context_instance=RequestContext(request))
    return render_to_response('test/authors_books_edits.html', {'author': a, 'authorsbooks': authorsbooks, 'formset': formset,}, context_instance=RequestContext(request))

模板

#all errors are here
{% for dict in form_errors %}
    {{ dict }}
{% endfor %}

#all forms are here, i want to pair the errors for each form
<form method="post" action="/test/{{ author.id }}/books/">
    {% csrf_token %}
        <table>
        {{ formset }}
        </table>
    <input type="submit" value="Submit"/>
    </form>

更新的模板:不显示错误

<form method="post" action="/test/{{ author.id }}/books/">
    {% formset.management_form %}
    {% csrf_token %}
    <table>
        {% for x in formset %}
        {{x.errors }}
        {{ x }}
        {% endfor %}
    </table>
<input type="submit" value="Submit"/>

【问题讨论】:

  • 您可以添加书籍和作者模型的来源以便我可以尝试吗?谢谢;)
  • "get_object_or_404(author, pk=author_id)" 应该是 "get_object_or_404(Author, pk=author_id)" (大写的作者)对吗?另外,您确定您的模型名为 Book 吗?看起来应该是书籍?
  • also: aurthorsbooks 应该是 authorsbooks
  • 是的,对不起,我正在复制但掩盖了一些变量。无论如何,结构本质上是相同的。并且仍然看不到错误..除了使用时:{% for dict in form_errors %} {{ dict }} {% endfor %}
  • 你能显示你想要的结果的伪html吗?我不太确定是否理解“我想为每个表单配对错误”

标签: django validation django-forms formset inline-formset


【解决方案1】:

编辑

authors_books_edits.html

<form method="post" action="/test/{{ author.id }}/books/">
    {% csrf_token %}
    {{ formset.management_form }}
    {% for form in formset.forms %}
        {{ form.non_field_errors }}
        {{ form.errors }}
        <table>
            {{ form.as_table }}
        </table>
    {% endfor %}
    <input type="submit" value="Submit"/>
</form>

views.py

from django.shortcuts import *
from django.forms.models import inlineformset_factory

from .models import *

def author_books_edit(request, author_id):
    a = get_object_or_404(Author, pk=author_id)
    authorsbooks = a.books_set.all()
    bookformset = inlineformset_factory(Author, Books, can_delete=True, can_order=True, exclude=('company',), extra=1)
    formset = bookformset(instance=a)
    if request.method == "POST":
        formset = bookformset(request.POST, request.FILES, instance=a)
        if formset.is_valid():
            formset.save()
        else:
            form_errors = formset.errors
            return render_to_response('authors_books_edits.html', {'author': a, 'authorsbooks': authorsbooks, 'formset': formset, 'form_errors': form_errors}, context_instance=RequestContext(request))
    return render_to_response('authors_books_edits.html', {'author': a, 'authorsbooks': authorsbooks, 'formset': formset,}, context_instance=RequestContext(request))

models.py

from django.db import models

class Author(models.Model):
    fname = models.CharField(max_length=100)
    lname = models.CharField(max_length=100)
    def fullname(self):
        return '%s %s' % (self.fname, self.lname)
    fullname = property(fullname)
    def __unicode__(self):
        return self.fullname

class Books(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=50)
    publisher = models.CharField(max_length=50)
    edition = models.CharField(max_length=50)
    comment = models.TextField()
    def __unicode__(self):
         return self.title

urls.py

from django.conf.urls.defaults import patterns, include, url

urlpatterns = patterns('testapp.views',
    url(r'test/(?P<author_id>\d+)/books/$', 'author_books_edit'),
)

您可以制作另一个临时应用来测试它。

看起来像这样:http://imageshack.us/photo/my-images/824/screenshotat20120227190.png/

== 结束编辑

您可以像这样迭代表单:

{% for form in formset.forms %}
   {{ form }}
{% endfor %}

在这种情况下,请参阅 Django 使用模板文档显示表单:https://docs.djangoproject.com/en/dev/topics/forms/#displaying-a-form-using-a-template

然后,更有趣的是,自定义表单模板(请参阅 form.non_field_errors): https://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

【讨论】:

  • 由于某种原因我的错误仍然没有出现。我已经更新了我的模板。我做错了什么?
  • 你试过 {{ x.non_field_errors }} 而不是 {{x.errors }} 吗?
  • 是的,x.non_field_errors 没有显示任何内容。这很奇怪,因为 {% for dict in form_errors %} {{ dict }} {% endfor %} 显示错误,只是与我的表单不成对...
  • 错误有两种:字段错误和非字段错误。要获取应显示在输入旁边的字段错误,请使用 {{ form.field_name.errors }}。要获取应显示在表单顶部的非字段错误,请调用 {{ form.non_field_errors }}
  • 感谢您的输入,但仍然没有出现错误。我把 {{ form.non_field_errors }} 放在 {{ form.management_form }} 下,我也把 {{ x.nameofmyfield.errors }} 就在 {{ x }} 上方,没有任何显示..我做错了什么?这让我发疯了。
【解决方案2】:

假设这本书是一种你可以做到的形式:

{% for b in authorsbooks %}
    {{b.errors}}
{% endfor %}

【讨论】:

  • 我更新了我的模板,但现在我收到一个错误并且页面已损坏...我已更新我的帖子以包含更新的模板。
  • 调试输出说了什么?
  • 它说 ValidationError [u'ManagementForm 数据丢失或已被篡改']
猜你喜欢
  • 2013-05-11
  • 1970-01-01
  • 2020-02-12
  • 2019-04-23
  • 2018-02-05
  • 2012-06-27
  • 1970-01-01
  • 2015-01-07
  • 1970-01-01
相关资源
最近更新 更多