24

Mar

Filed in Code, Django with 6 comments |

Today I was creating the submission form for the new iBegin.com homepage. In this we use a lot of JavaScript to make the process more clean. One such use, was an autocomplete on Cities and Categories. To do this, and to keep validation, you need to use a ModelChoiceField, but using a ModelChoiceField with a TextInput doesn’t work. So, I give you an InlineModelChoiceField in Django.

from django import newforms as forms
 
class InlineModelChoiceField(forms.ModelChoiceField):
    def __init__(self, *args, **kwargs):
        kwargs['widget'] = kwargs.pop('widget', forms.widgets.TextInput)
        super(InlineModelChoiceField, self).__init__(*args, **kwargs)
 
    def clean(self, value):
        if not value and not self.required:
            return None
        try:
            return self.queryset.filter(name=value).get()
        except self.queryset.model.DoesNotExist:
            raise forms.ValidationError("Please enter a valid %s." % (self.queryset.model._meta.verbose_name,))

6 Responses to "ModelChoiceFields as CharFields in Django"

Subscribe to this topic with RSS or get the Trackback URL
Fidel Ramos (Mar 26th):

Very interesting, the flexibility of Django’s newforms doesn’t cease to amaze me.

Is this code intended for trunk? Wouldn’t you need to define get_internal_type()?

Also, is there a good reason to use filter(name=value).get() instead of get(name=value)?

David (Mar 26th):

I don’t know much about newforms internals beyond what I’ve hacked out of it, so you may need get_internal_type (but this works).

As for the .filter().get() I think I had it doing .filter()[0:1] at first, so that’s just a slip on my part.

Michael (Mar 26th):

get_internal_type() is for model fields only (unrelated to newforms);

I’m actually in need of something similar right now, but I’m not comfortable with using a name string for defining the selection - primarily since I can’t guarantee uniqueness. Instead I’m using a hidden field to pass the id, which the JQuery autocomplete widget from bassistance.de supports nicely using the .result() hook (not sure what you are using of course).

Elliott (Mar 26th):

Thanks for this. Its almost exactly what I needed.
Any chance that you could enlighten us on the auto complete stack that you are using?

David (Mar 26th):

I’m using a mootools component, and just a custom view to spit it out. I’m planning out distributing my newfroms utilities here in the near future, which will include some sort of ajax controls.

Elliott (Mar 26th):

That would be AWESOME; thanks for being such a big contributor to OS.

Leave A Reply

 Username (*required)

 Email Address (*private)

 Website (*optional)

Note: Comments moderation may be active so there is no need to resubmit your comment.