2012-02-24 30 views
5

Tengo un modelo de autor y un modelo de libros. Un usuario puede modificar las propiedades de todos los libros de un autor determinado. Quiero poder mostrar los errores para cada libro individual en lugar de tener todos los errores enumerados en la parte superior. ¿Cómo puedo hacer esto?Django: cómo mostrar errores de formulario para cada objeto de modelo en un formset en línea

MODELOS

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 

VER

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)) 

PLANTILLA

#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> 

plantilla actualizada: no muestra errores

<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"/> 

+0

¿Puede agregar la fuente de libros y el modelo de autor para que pueda probarlo? gracias;) – jpic

+0

@jpic modelos añadidos para ya – thedeepfield

+0

"get_object_or_404 (author, pk = author_id)" debería ser "get_object_or_404 (Author, pk = author_id)" (Autor en mayúscula) ¿verdad? Además, ¿estás seguro de que tu modelo se llama Libro? Parece que debería ser Libros? – jpic

Respuesta

9

EDITAR

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'), 
) 

Usted puede hacer otra aplicación temporal para probarlo.

Parece que este: http://imageshack.us/photo/my-images/824/screenshotat20120227190.png/

END == EDITAR

Usted puede iterar sobre las formas como tal:

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

En ese caso, consulte el Django de mostrar un formulario utilizando una plantilla documentación: https://docs.djangoproject.com/en/dev/topics/forms/#displaying-a-form-using-a-template

Entonces, más interesante, personalizando una plantilla de formulario (vea form.non_field_errors): https://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

+0

por alguna razón, mis errores aún no aparecen. He actualizado mi plantilla. ¿Qué estoy haciendo mal? – thedeepfield

+0

¿Intentó {{x.non_field_errors}} en lugar de {{x.errors}}? – jpic

+0

sí, x.non_field_errors no muestra nada. Es extraño porque {% para dict en form_errors%} {{dict}} {% endfor%} muestra errores, simplemente no está en pareja con mis formularios ... – thedeepfield

1

Suponiendo que el libro es una forma que podría hacer:

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

actualicé mi plantilla, pero ahora me sale un error y la página es roto ... He actualizado mi publicación para incluir la plantilla actualizada. – thedeepfield

+0

¿Qué dice la salida de depuración? – Nix

+0

dice ValidationError [u'ManagementForm datos falta o ha sido alterado] ' – thedeepfield

Cuestiones relacionadas