tags:

views:

487

answers:

1

Got an interesting dilemna here as I've tried to create an autocomplete widget for my Django app.

The basic structure of the model is that I have 1 .. * Orders that each belong to a single Vendor. Since we have many Vendors I decided to make it an autocomplete widget instead of a big selectbox dropdown.

With that in mind, I came up with this: http://dpaste.com/21752/

The widget is called like so:

self.fields['vendor'].widget = AutoCompleteWidget(reverse('vendor_search'), { .. attrs .. })

It's not complete, and there is some code that makes no sense but that's just me toying with Django widgets to understand how things work (e.g I know the attrs passing is totally bogus)

But that's beyond the point. This Widget works in the sense that I type a vendor name, it spits back a list of all vendors matching the substring and I can select it, save and viola

Only issue? When I load the page to edit an Order, it shows the vendor id instead of the name, makes sense since that's what is stored in the database but it's not very pleasant for the user.

I've toyed with the idea of using a ModelChoiceField but it requires a queryset to be passed, and in this case, you need a dynamic query as it will be modified based on the users search.

Thanks in advance for any help, SO has been very helpful so far with my previous questions! :)

A: 

Had the same question the other day and went to check the ModelChoiceField code to understand how it works. No black magic there, while creating their list from the query they match the corresponding id with the value to be displayed.

In your autocomplete case it's not efficient to select all the rows to find your own, thus you might have to pass a queryset to your widget to teach him how to fetch the corresponding element

self.fields['vendor'].widget = AutoCompleteWidget(Vendor.objects.all(), reverse('vendor_search'), { .. attrs .. })

In AutoCompleteWidget, to get your value :

def init(self, queryset, url, *args):
    self.queryset = queryset
    [...]

def render(self, value, ...):
    text = unicode(queryset.get(id = value)) # either that, or queryset.get(id = value).name
    [...]
Guillaume Esquevin