views:

515

answers:

2

I have a modelform which has one field that is a ForeignKey value to a model which as 40,000 rows. The default modelform tries to create a select box with 40,000 options, which, to say the least is not ideal. Even more so when this modelform is used in a formset factory!

In the admin, this is easiely avoidable by using "raw_id_fields", but there doesn't seem to be a modelform equivalent. How can I do this?

Here is my modelform:

class OpBaseForm(ModelForm):

    base = forms.CharField()

    class Meta:
        model = OpBase
        exclude = ['operation', 'routes']
        extra = 0
        raw_id_fields = ('base', )   #does nothing

The first bolded line works by not creating the huge unwieldy selectbox, but when I try to save a fieldset of this form, I get the error: "OpBase.base" must be a "Base" instance. In order for the modelform to be saved, 'base' needs to be a Base instance. Apparently, a string representation of a Base primary key isn't enough (at least not automatically). I need some kind of mechanism to change the string that is given my the form, to a Base instance. And this mechanism has to work in a formset. Any ideas? If only raw_id_fields would work, this would be easy as cake. But as far as I can tell, it only is available in the admin.

A: 

You need to change the widget for the base field, not the field type. I think this would work:

class OpBaseForm(ModelForm):
    base = forms.ModelChoiceField(queryset=Base.objects.all(), 
                                  widget=forms.TextInput)

    class Meta:
        model = OpBase
        ... etc...
Daniel Roseman
welp, that did it, thanks a lot!
nbv4
A: 

can you possibly post your final working version here? I know this is old and all but I can't seem to figure out how to do this either and that method doesn't really do anything for me. Did you include some extra JS etc on the template rendering the modelform?

Mike