On Mon, Aug 24, 2009 at 6:27 AM, David Haas<david.h.h...@gmail.com> wrote: > > Hi: > > Yet again, I've run into a behavior change which seems to be linked to > svn revision 10190. I've figured out a workaround for my code, but > I'm wondering if someone could provide some feedback if the change is > just a definition of previously undefined behavior, or a bug. > > I've pasted some demo code here: http://dpaste.de/PUvT/ > > Basically, I have 2 models "A" and "B" with a many-to-many > relationship through "ABExtra". I have a modelform where I can make > new instances of "B", with a inline modelformset for adding in > ABExtras. > > In r. 10189, the pasted view code works just fine - I create my new > model B, pass it into my formset forms, then save the formsets. > > In r.10190, the code throws an integrity error. "abextra.modelb_id > may not be NULL" > > I've worked around this bug by doing the following: > > new_b = form.save() > for f in formset.forms: > f.cleaned_data['ma'] = new_b > nbs= formset.save(commit=false) > for b in nbs: > b.ma = new_b > b.save() > > But this seems a little redundant. Can someone explain why the > behavior changed, or maybe a better way for me to save my form & > formset?
It isn't so much that the behaviour changed - it's that a behaviour that previously shouldn't have worked - but did for some reason - now doesn't work at all :-) Your "working" code correctly identifies the fact that the FormSet instance needs to be bound to an instance of ModelB, but doesn't do so in the right way. Rather than providing the instance as the 'instance' argument to the FormSet, you're trying to sneak it into the form data. The right way to structure your view is something like the following: form = forms.ModelBAddForm(request.POST) if form.is_valid(): form_validated = True new_model_b = form.save(commit=False) else: form_validated = False new_model_b = ModelB() formset = MBFormSet(instance=new_model_b, data=request.POST) if form_validated and formset.is_valid(): formset.save() return HttpResponseRedirect('../success') That is: * validate the base form, but don't commit the new object; * construct a formset instance that uses the constructed, but unsaved instance; * validate that both the form and formset are OK; * save the original object and the formset. Yours, Russ Magee %-) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---