Opened 17 years ago
Closed 14 years ago
#9538 closed New feature (fixed)
modelformset_factory cannot easily be used for only inserting
| Reported by: | Collin Grady | Owned by: | Brian Rosner |
|---|---|---|---|
| Component: | Forms | Version: | 1.3 |
| Severity: | Normal | Keywords: | modelform |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | yes |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
I just finished adding multi-file uploading to a little file management app I'm making, and it was far more difficult than it had to be to make it stop showing existing models as well as new forms.
modelformset_factory should have an option to work in add-only mode - I had to make my own subclass of BaseModelFormSet and set the queryset to an empty list to make it stop showing current models, which is quite a hack :)
Change History (9)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
That doesn't seem to work - I tried queryset=Image.objects.none() and queryset=[] and neither changed anything - only my subclass method worked
comment:3 by , 17 years ago
| Needs documentation: | set |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
| Triage Stage: | Unreviewed → Accepted |
I took a minute to look into this. I am not seeing any odd behavior with use an empty queryset.
In [1]: from django.forms.models import modelformset_factory
In [2]: from satchmo.apps.product.models import Product
In [3]: FormSet = modelformset_factory(Product, fields=("sku",), extra=3)
In [4]: formset = FormSet(queryset=Product.objects.none())
In [5]: for form in formset.forms:
...: print form.as_p()
...:
<p><label for="id_form-0-sku">SKU:</label> <input id="id_form-0-sku" type="text" name="form-0-sku" maxlength="150" /><input type="hidden" name="form-0-id" id="id_form-0-id" /></p>
<p><label for="id_form-1-sku">SKU:</label> <input id="id_form-1-sku" type="text" name="form-1-sku" maxlength="150" /><input type="hidden" name="form-1-id" id="id_form-1-id" /></p>
<p><label for="id_form-2-sku">SKU:</label> <input id="id_form-2-sku" type="text" name="form-2-sku" maxlength="150" /><input type="hidden" name="form-2-id" id="id_form-2-id" /></p>
It appears to work fine for me. I would recommend creating a new ticket on a specific issue with doing the above. I want to commit a documentation fix for this however since it seems like a worthy item to document.
comment:4 by , 16 years ago
I think I have a similiar problem. queryset=Subscriber.objects.none() works fine and it displays no initial data in form creation but if you try to save a (empty) formset, the formset tries to validate the same count of rows as the model have.
Uh? Here is a screenshot: http://img.mahner.org/formerror-20090602-165834.jpg The Subscriber model has 6 entries which the formset tries to "compare".
SubscriberFormSet = modelformset_factory(Subscriber, max_num=0, extra=10,
fields=('active', 'salutation', 'first_name', 'last_name', 'email',))
formset = SubscriberFormSet(queryset=Subscriber.objects.none())
if request.method == 'POST':
formset = SubscriberFormSet(request.POST)
if formset.is_valid():
formset.save(commit=False)
comment:5 by , 16 years ago
Ignore my comment, I've forgot the queryset=Subscriber.objects.none() in the second SubscriberFormSet() instance. Works fine.
comment:6 by , 15 years ago
| Severity: | → Normal |
|---|---|
| Type: | → New feature |
comment:7 by , 14 years ago
| Easy pickings: | unset |
|---|---|
| Resolution: | → fixed |
| Status: | assigned → closed |
| UI/UX: | unset |
I think the docs are pretty clear on this matter currently:
https://docs.djangoproject.com/en/1.3/topics/forms/modelforms/#changing-the-queryset
If you want to return a formset that doesn't include any pre-existing instances of the model, you can specify an empty QuerySet: >>> AuthorFormSet(queryset=Author.objects.none())
Hence closing this ticket.
comment:8 by , 14 years ago
| Keywords: | modelform added |
|---|---|
| Resolution: | fixed |
| Status: | closed → reopened |
| Version: | 1.0 → 1.3 |
Ive got error in this sample program CSRF verification failed. Request aborted.
from myform.xforms.models import Author
from django.forms.models import modelformset_factory
from django.shortcuts import render_to_response, get_object_or_404,HttpResponse
def index(request):
AuthorFormSet = modelformset_factory(Author)
if request.method == 'POST':
formset = AuthorFormSet(request.POST,request.FILES)
if formset.is_valid():
formset.save()
else:
formset = AuthorFormSet()
return render_to_response("authors.html",{"formset":formset,})
# Create your views here.
comment:9 by , 14 years ago
| Resolution: | → fixed |
|---|---|
| Status: | reopened → closed |
This is a CSRF verification problem, and it doesn't look related to the problem originally described by this ticket.
I suggest reviewing the CSRF docs, and if you can't figure out what's going wrong, asking for help on the #django IRC channel or the django-users mailing list.
You don't need to subclass
BaseModelFormSet. You can pass in a queryset to the constructor of the formset:I don't see the point in adding a way to do this outside of just passing in an empty queryset. I would prefer to make a documentation change here.