Reputation: 308909
I am using django's inline formset factory. To use the example in the docs,
author = Author.objects.get(pk=1)
BookFormSet = inlineformset_factory(Author, Book)
formset = BookFormSet(request.POST, instance=author)
will create an inline formset to edit books by a particular author.
I want to create a formset that only allows users to add new books by that author, not edit existing books. Is there a simple way to use inlineformset_factory to do this?
Upvotes: 11
Views: 3935
Reputation: 3840
Based on Jeremy Lewis and if you don't want to subclass BaseInlineFormSet, you can just give an empty queryset parameter to your BookFormSet.
See pseudo (untested) Django 1.6 code sample:
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, })
Upvotes: 3
Reputation:
Actually the answer is given in the documentation. Just don't give any instance to the FormSet. From the 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
You can then create view as follows:
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,
Hope it helps.
Upvotes: 0
Reputation: 1719
inlineformset_factory takes a formset kwarg, which defaults to BaseInlineFormSet. BaseInlineFormSet subclasses BaseModelFormSet, which defines a get_queryset method. If you create a BaseInlineFormSet subclass and override get_queryset to return EmptyQuerySet(), you should get what you're after. In the above example then, it would look like this:
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)
Upvotes: 9