Returning a model's PK from an AutoCompleteWidget?

22 views
Skip to first unread message

Derek Hohls

unread,
Oct 11, 2016, 3:51:20 PM10/11/16
to django-selectable
Hi

I am trying to get a lookup to display text (from a `code` field) for my Site 
model in the autocomplete, but when the form returns the data to the view, 
it should be the corresponding primary key.

# forms.py

    site = forms.CharField(
        widget=AutoCompleteWidget(SiteLookup),
        label=_u('TREES_NEWINFUSION_SITE_name'),
        required=False)

# lookup.py

class SiteLookup(ModelLookup):
    model = Site
    search_fields = (
        'code__icontains',
        'alias__icontains',
    )

    def get_item_id(self, item):
        return item   # FIRST ATTEMPT

try:
    registry.register(SiteLookup)
except LookupAlreadyRegistered:
    pass

Traceback (most recent call last):
  File "/home/gamesbook/.virtualenvs/bldg/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 112, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/gamesbook/.virtualenvs/bldg/local/lib/python2.7/site-packages/selectable/views.py", line 15, in get_lookup
    return lookup.results(request)
  File "/home/gamesbook/.virtualenvs/bldg/local/lib/python2.7/site-packages/selectable/base.py", line 103, in results
    content = self.serialize_results(results)
  File "/home/gamesbook/.virtualenvs/bldg/local/lib/python2.7/site-packages/selectable/base.py", line 128, in serialize_results
    return json.dumps(results, cls=DjangoJSONEncoder, ensure_ascii=False)
  File "/usr/lib/python2.7/json/__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/home/gamesbook/.virtualenvs/bldg/local/lib/python2.7/site-packages/django/core/serializers/json.py", line 104, in default
    return super(DjangoJSONEncoder, self).default(o)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <Site: ACCSO01> is not JSON serializable


But:

class SiteLookup(ModelLookup):
    model = Site
    search_fields = (
        'code__icontains',
        'alias__icontains',
    )

    def get_item_id(self, item):
        return item.pk   # SECOND ATTEMPT

try:
    registry.register(SiteLookup)
except LookupAlreadyRegistered:
    pass


Just returns the Site code as a string, and not the Site's ID value.

What is the correct combination to get back the data that I need?

Thanks
Derek

Mark Lavin

unread,
Oct 11, 2016, 4:08:38 PM10/11/16
to django-s...@googlegroups.com
The AutoCompleteWidget is used for completing text not for selecting objects: http://django-selectable.readthedocs.io/en/latest/widgets.html#autocompletewidget

AutoCompleteWidget
Basic widget for auto-completing text. The widget returns the item value as defined by the lookup get_item_value.

If you want to select objects then you should be using one of the AutoCompleteSelectWidget widget (or rather the AutoCompleteSelectField): http://django-selectable.readthedocs.io/en/latest/widgets.html#autocompleteselectwidget

 AutoCompleteSelectWidget
Widget for selecting a value/id based on input text. Optionally allows selecting new items to be created. This widget should be used in conjunction with the AutoCompleteSelectField as it will return both the text entered by the user and the id (if an item was selected/matched).

This uses the get_item_label for the dropdown display, get_item_value for the value in the input once selected, and get_item_id to determine PK (the default should be what you want here). 

--
You received this message because you are subscribed to the Google Groups "django-selectable" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-selectable+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Derek Hohls

unread,
Oct 12, 2016, 12:30:04 PM10/12/16
to django-selectable
Thanks Mark; I should have spotted that difference.

Just for the record, I only had to do this:

class SiteLookup(ModelLookup):
    model = Site
    search_fields = (
        'code__icontains',
        'alias__icontains',
    )

try:
    registry.register(SiteLookup)
except LookupAlreadyRegistered:
    pass


with :
    site = forms.ModelChoiceField(
        widget=AutoCompleteSelectWidget(lookup_class=SiteLookup),
        label='Site',
        queryset=Site.objects.all(),
        required=False)

To unsubscribe from this group and stop receiving emails from it, send an email to django-selecta...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages