2010-03-01 13 views
8

Estoy usando la fábrica de formset en línea de django. Para utilizar el ejemplo en la documentación,Límite de Inlineformset_factory de Django para crear solo objetos nuevos

author = Author.objects.get(pk=1) 
BookFormSet = inlineformset_factory(Author, Book) 
formset = BookFormSet(request.POST, instance=author) 

creará un juego de formularios en línea para editar libros de un autor en particular.

Quiero crear un formset que solo permita a los usuarios agregar libros nuevos de ese autor, no editar libros existentes. ¿Hay una manera simple de usar inlineformset_factory para hacer esto?

Respuesta

6

inlineformset_factory toma un formset kwarg, que por defecto es BaseInlineFormSet. Subclases BaseInlineFormSet BaseModelFormSet, que define un método get_queryset. Si crea una subclase BaseInlineFormSet y anula get_queryset para devolver EmptyQuerySet(), debe obtener lo que busca. En el ejemplo anterior, entonces, se vería así:

from django.db.models.query import EmptyQuerySet 
from django.forms.models import BaseInlineFormSet 

class BaseInlineAddOnlyFormSet(BaseInlineFormSet): 
    def get_queryset(self): 
     return EmptyQuerySet() 

author = Author.objects.get(pk=1) 
BookFormSet = inlineformset_factory(Author, Book, formset=BaseInlineAddOnlyFormSet) 
formset = BookFormSet(request.POST, instance=author) 
+1

[Los docs] (https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#changing-the- queryset) parece decir que la forma preferida de establecer el queryset es anulada '__init__' después de llamar a super. Pero eso no está funcionando para mí. Su método lo hace, al igual que la configuración de kwarg 'queryset' antes de llamar a super' '__init__'. Gracias. –

0

En realidad, la respuesta se da en la documentation. Simplemente no des ninguna instancia al FormSet. Desde el doc:

>>> from django.forms.models import inlineformset_factory 
>>> BookFormSet = inlineformset_factory(Author, Book) 
>>> author = Author.objects.get(name=u'Mike Royko') 
>>> formset = BookFormSet() # This will create an empty form with your model fields 

continuación, puede crear la vista de la siguiente manera:

if request.method == "POST": 
    formset = BookFormSet(request.POST, request.FILES) 
    if formset.is_valid(): 
     formset.save() 
else: 
    formset = BookFormSet() 
return render_to_response("add_book.html", { 
    "formset": formset, 

espero que ayude.

+0

Esto no funciona para mí; todavía llena el formset con todos los 'Book's. django 1.4. –

1

Basado en Jeremy Lewis y si no desea subclasificar BaseInlineFormSet, puede dar un parámetro de conjunto de consulta vacío a su BookFormSet.

Ver muestra seudo (no probado) Django 1,6 código:

BookFormSet = inlineformset_factory(parent=Author, model=Book) 
if request.method == "POST": 
    formset = BookFormSet(request.POST, request.FILES, instance=author) 
    if formset.is_valid(): 
     formset.save() 
else: 
    queryset = Book.objects.none() # does not allow to edit books 
    formset = BookFormSet(instance=project, initial=initial, queryset=queryset) 
return render(request, "add_book.html", { "formset": formset, }) 
+0

inlineformset_factory ahora requiere que se especifique explícitamente el parámetro 'fields'. Solo una actualización. – Rexford

Cuestiones relacionadas