Another django formset issue (initial values)

2,820 views
Skip to first unread message

Ofer Koren

unread,
Feb 28, 2011, 5:50:40 AM2/28/11
to pywe...@googlegroups.com
I'll use my previous example again.
Basically it fails because of the initial value set on the InstrumentForm.
The formset thinks the empty form as changed (as if the Instrument field was modified to the initial value), and because some other fields are required and not filled, fails validation.
I would expect supplying an 'initial' value to a field wouldn't cause the form to be regarded as modified.
Any ideas what I might be doing wrong?


# (models.py):

class InstrumentType(Model):
    name = CharField(...)


class Instrument(Model):

    auth_user = ForeignKey(User)
    instrument = ForeignKey(InstrumentType)
    model = CharField(required=True)

# (forms.py):

class InstrumentForm(django.forms.ModelForm):

    instrument = forms.ModelChoiceField(
                queryset=Instrument.objects.all(), 
                initial=Instrument.objects.get(name='guitar')
                )

    class Meta:
        model = Instrument
        exclude = ('auth_user',)

# (views.py):

InstrumentsFormSet = modelformset_factory(
                                Instrument, 
                                can_delete=True, 
                                form=InstrumentForm)


def manage_instruments_view(request):
    user_instruments = Instrument.objects.filter(auth_user=request.user)
    if request.method == "GET":
        formset = InstrumentsFormSet(queryset=user_instruments)
    elif request.method == "POST":
        formset = InstrumentsFormSet(request.POST, queryset=user_instruments)
        if formset.is_valid():       # <--------------------------- fails here
            for form in formset.forms:
                form.instance.auth_user = request.user
            instances = formset.save()
            return HttpResponseRedirect('/saved/')
        else:
            pass   # invalid data

    return direct_to_template(request, 'users/form_update_profile.html', extra_context=loca

- Ofer
www.mrbroken.com

Meir Kriheli

unread,
Feb 28, 2011, 6:24:11 AM2/28/11
to pywe...@googlegroups.com, Ofer Koren
Hi,

On 02/28/2011 12:50 PM, Ofer Koren wrote:
> I'll use my previous example again.
> Basically it fails because of the initial value set on the InstrumentForm.

> The formset thinks the empty form as /changed/ (as if the Instrument
> field was /modified /to the /initial/ value), and because some other


> fields are required and not filled, fails validation.
> I would expect supplying an 'initial' value to a field wouldn't cause
> the form to be regarded as modified.
> Any ideas what I might be doing wrong?
>

Set initial during formset instantiation:

http://docs.djangoproject.com/en/dev/topics/forms/formsets/#using-initial-data-with-a-formset

Cheers
--
Meir Kriheli

>
> # (models.py):
>
> class InstrumentType(Model):
> name = CharField(...)
>
>
> class Instrument(Model):
>
> auth_user = ForeignKey(User)
> instrument = ForeignKey(InstrumentType)
> model = CharField(required=True)
>
> # (forms.py):
>
> class InstrumentForm(django.forms.ModelForm):
>

> *


> instrument = forms.ModelChoiceField(
> queryset=Instrument.objects.all(),
> initial=Instrument.objects.get(name='guitar')
> )

> *

> www.mrbroken.com <http://www.mrbroken.com>
>
> --
> You received this message because you are subscribed to the Google
> Groups "PyWeb-IL" group.
> To post to this group, send email to pywe...@googlegroups.com.
> To unsubscribe from this group, send email to
> pyweb-il+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/pyweb-il?hl=en.

Ofer Koren

unread,
Feb 28, 2011, 7:04:54 AM2/28/11
to Meir Kriheli, pywe...@googlegroups.com
That is an awkward feature - it forces me to count the number of model instances in my query-set, add the number of extra forms, and then create that many initial-data-dictionaries:

myset = MyModel.objects.filter(auth_user=request.user)
formset = MyFormSet(queryset = myset, initial = [{'instrument_type':Instrument.objects.get(name='guitar')}]*(myset.count()+num_extra_forms)

- Ofer
www.mrbroken.com

Ofer Koren

unread,
Mar 6, 2011, 11:43:28 AM3/6/11
to Meir Kriheli, pywe...@googlegroups.com
Any other ideas?... or have I misunderstood?

- Ofer
www.mrbroken.com

Shai Berger

unread,
Mar 7, 2011, 2:16:25 AM3/7/11
to pywe...@googlegroups.com
On Sunday 06 March 2011, Ofer Koren wrote:
> Any other ideas?... or have I misunderstood?
>

I think you misunderstood initial data: Forms with initial data are not
considered "empty unless something changed". An empty form is only one where
all fields are empty.

You can get the behavior you want by overriding the formset's clean() method:
http://docs.djangoproject.com/en/dev/topics/forms/formsets/#custom-formset-
validation

Shai.

Shai Berger

unread,
Mar 7, 2011, 2:52:06 AM3/7/11
to pywe...@googlegroups.com, Ofer Koren, Meir Kriheli
On second thought...

On Sunday 06 March 2011, Ofer Koren wrote:

> >> > # (views.py):
> >> >
> >> > InstrumentsFormSet = modelformset_factory(
> >> >
> >> > Instrument,
> >> > can_delete=True,
> >> > form=InstrumentForm)
> >> >
> >> > def manage_instruments_view(request):
> >> > user_instruments =
> >> > Instrument.objects.filter(auth_user=request.user)
> >> >
> >> > if request.method == "GET":
> >> > formset = InstrumentsFormSet(queryset=user_instruments)
> >> >
> >> > elif request.method == "POST":
> >> > formset = InstrumentsFormSet(request.POST,
> >> >
> >> > queryset=user_instruments)

Why are you passing in the queryset here?

Shai.

Ofer Koren

unread,
Mar 7, 2011, 6:56:58 AM3/7/11
to pywe...@googlegroups.com, Shai Berger, Meir Kriheli
I'm basically following the django examples:


Regarding initial-data: django seems to skip validation/saving of a form in a formset if it hasn't changed. This is determined by the 'has_changed' method, which checks the current values against the initial values. However it seems to to be buggy when the initial value is being set in the Form definition (as opposed to Formset instantiation).

- Ofer
www.mrbroken.com



--
Reply all
Reply to author
Forward
0 new messages