jMyles
jMyles

Reputation: 12162

Specifying default value for hidden ModelChoiceField (Django)

So let's say at the last minute (in the view) I decide I want to specify a default for a field and make it hidden, like so:

form.fields['coconut'] = forms.ModelChoiceField(
    label="", 
    widget=forms.HiddenInput(),
    queryset=swallow.coconuts.all(),
    initial=some_particular_coconut,
)

My question is this: Do I really need to specify queryset here? I mean, I already know, from initial, exactly which coconut I'm talking about. Why do I also need to specify that the universe of available coconuts is the set of coconuts which this particular swallow carried (by the husk)?

Is there a way I can refrain from specifying queryset? Simply omitting causes django to raise TypeError.

If indeed it is required, isn't this a bit damp?

Upvotes: 5

Views: 13859

Answers (3)

Guillermo Siliceo Trueba
Guillermo Siliceo Trueba

Reputation: 4619

I think is good that stackoverflow answers point to the 'right' way to do things, but increasingly the original question goes unanswered because the user was trying to do the wrong thing. So to answer this question directly this is what you can do:

form.fields['coconut'] = forms.ModelChoiceField(label="", widget=forms.HiddenInput(attrs={'value':some_particular_coconut}), queryset=swallow.coconuts.all())

Notice the named argument passed to HiddenInput, its super hackish but its a direct answer to the original question.

Upvotes: 12

Thomas
Thomas

Reputation: 11888

The reason django requires a queryset is because when you render the field to the page, django only sends the id. when it comes back, it needs knowlege of the queryset in order to re-inflate that object. if you already know the queryset at form creation time, why not simply specify form.fields['coconut'].initial = some_particular_coconut in your view and leave the rest of the definition in your forms.py?

If you find that you only really need to send the id anyway (you don't have to re-inflate to an object at your end), why not send it in a char field?

Upvotes: 0

Robert
Robert

Reputation: 6540

The problem is that you're trying to set up a hidden ModelChoiceField. In order to have a Choice (dropdown, traditionally) it needs to know its Choices - this is why you give a queryset.

But you're not trying to give the user a choice, right? It's a hidden input, and you're setting it from the server (so it gets POSTed back, presumably).

My suggestion is to try to find a way around using the hidden input at all. I find them a bit hacky. But otherwise, why not just specify a text field with some_particular_coconut.id, and hide that? The model's only wrapping that id anyway.

Upvotes: 3

Related Questions