Source

django-selectable / docs / lookups.rst

Full commit

Defining Lookups

What are Lookups?

Lookups define the corresponding ajax views used by the auto-completion fields and widgets. They take in the current request and return the JSON needed by the jQuery auto-complete plugin.

Defining a Lookup

django-selectable uses a registration pattern similar to the Django admin. Lookups should be defined in a lookups.py in your application's module. Once defined you must register in with django-selectable. All lookups must extend from selectable.base.LookupBase which defines the API for every lookup.

from selectable.base import LookupBase
from selectable.registry import registry

class MyLookup(LookupBase):
    def get_query(self, request, term):
        data = ['Foo', 'Bar']
        return filter(lambda x: x.startswith(term), data)

registry.register(MyLookup)

Lookup API

There are also some additional methods that you could want to use/override. These are for more advanced use cases such as using the lookups with JS libraries other than jQuery UI. Most users will not need to override these methods.

Lookups Based on Models

Perhaps the most common use case is to define a lookup based on a given Django model. For this you can extend selectable.base.ModelLookup. To extend ModelLookup you should set two class attributes: model and search_fields.

The syntax for search_fields is the same as the Django field lookup syntax. Each of these lookups are combined as OR so any one of them matching will return a result. You may optionally define a third class attribute filters which is a dictionary of filters to be applied to the model queryset. The keys should be a string defining a field lookup and the value should be the value for the field lookup. Filters on the other hand are combined with AND.

User Lookup Example

Below is a larger model lookup example using multiple search fields, filters and display options for the auth.User model.

from django.contrib.auth.models import User
from selectable.base import ModelLookup
from selectable.registry import registry


class UserLookup(ModelLookup):
    model = User
    search_fields = (
        'username__icontains',
        'first_name__icontains',
        'last_name__icontains',
    )
    filters = {'is_active': True, }

    def get_item_value(self, item):
        # Display for currently selected item
        return item.username

    def get_item_label(self, item):
        # Display for choice listings
        return u"%s (%s)" % (item.username, item.get_full_name())

registry.register(UserLookup)

Lookup Decorators

Registering lookups with django-selectable creates a small API for searching the lookup data. While the amount of visible data is small there are times when you want to restrict the set of requests which can view the data. For this purpose there are lookup decorators. To use them you simply decorate your lookup class.

from django.contrib.auth.models import User
from selectable.base import ModelLookup
from selectable.decorators import login_required
from selectable.registry import registry


@login_required
class UserLookup(ModelLookup):
    model = User
    search_fields = ('username__icontains', )
    filters = {'is_active': True, }

registry.register(UserLookup)

Note

The class decorator syntax was introduced in Python 2.6. If you are using django-selectable with Python 2.5 you can still make use of these decorators by applying the without the decorator syntax.

class UserLookup(ModelLookup):
    model = User
    search_fields = ('username__icontains', )
    filters = {'is_active': True, }

UserLookup = login_required(UserLookup)

registry.register(UserLookup)

Below are the descriptions of the available lookup decorators.

ajax_required

The django-selectable javascript will always request the lookup data via XMLHttpRequest (AJAX) request. This decorator enforces that the lookup can only be accessed in this way. If the request is not an AJAX request then it will return a 400 Bad Request response.

login_required

This decorator requires the user to be authenticated via request.user.is_authenticated. If the user is not authenticated this will return a 401 Unauthorized response. request.user is set by the django.contrib.auth.middleware.AuthenticationMiddleware which is required for this decorator to work. This middleware is enabled by default.

staff_member_required

This decorator builds from login_required and in addition requires that request.user.is_staff is True. If the user is not authenticatated this will continue to return at 401 response. If the user is authenticated but not a staff member then this will return a 403 Forbidden response.