Import newer version of django-selectable
[pgweb/local.git] / dep / django-selectable / docs / lookups.rst
blob5bb7cda5ecb2980418cca26094ab714fa545afaf
1 Defining Lookups
2 ==================
4 What are Lookups?
5 --------------------------------------
7 Lookups define the corresponding ajax views used by the auto-completion
8 fields and widgets. They take in the current request and return the JSON
9 needed by the jQuery auto-complete plugin.
12 Defining a Lookup
13 --------------------------------------
15 django-selectable uses a registration pattern similar to the Django admin.
16 Lookups should be defined in a `lookups.py` in your application's module. Once defined
17 you must register in with django-selectable. All lookups must extend from
18 ``selectable.base.LookupBase`` which defines the API for every lookup.
20     .. code-block:: python
22         from selectable.base import LookupBase
23         from selectable.registry import registry
25         class MyLookup(LookupBase):
26             def get_query(self, request, term):
27                 data = ['Foo', 'Bar']
28                 return [x for x in data if x.startswith(term)]
30         registry.register(MyLookup)
33 Lookup API
34 --------------------------------------
36 .. py:method:: LookupBase.get_query(request, term)
38     This is the main method which takes the current request
39     from the user and returns the data which matches their search.
41     :param request: The current request object.
42     :param term: The search term from the widget input.
43     :return: An iterable set of data of items matching the search term.
45 .. _lookup-get-item-label:
47 .. py:method:: LookupBase.get_item_label(item)
49     This is first of three formatting methods. The label is shown in the
50     drop down menu of search results. This defaults to ``item.__unicode__``.
52     :param item: An item from the search results.
53     :return: A string representation of the item to be shown in the search results.
54         The label can include HTML. For changing the label format on the client side
55         see :ref:`Advanced Label Formats <advanced-label-formats>`.
58 .. py:method:: LookupBase.get_item_id(item)
60     This is second of three formatting methods. The id is the value that will eventually
61     be returned by the field/widget. This defaults to ``item.__unicode__``.
63     :param item: An item from the search results.
64     :return: A string representation of the item to be returned by the field/widget.
66 .. py:method:: LookupBase.get_item_value(item)
68     This is last of three formatting methods. The value is shown in the
69     input once the item has been selected. This defaults to ``item.__unicode__``.
71     :param item: An item from the search results.
72     :return: A string representation of the item to be shown in the input.
74 .. py:method:: LookupBase.get_item(value)
76     ``get_item`` is the reverse of ``get_item_id``. This should take the value
77     from the form initial values and return the current item. This defaults
78     to simply return the value.
80     :param value: Value from the form inital value.
81     :return: The item corresponding to the initial value.
83 .. py:method:: LookupBase.create_item(value)
85     If you plan to use a lookup with a field or widget which allows the user
86     to input new values then you must define what it means to create a new item
87     for your lookup. By default this raises a ``NotImplemented`` error.
89     :param value: The user given value.
90     :return: The new item created from the item.
92 .. _lookup-format-item:
94 .. py:method:: LookupBase.format_item(item)
96     By default ``format_item`` creates a dictionary with the three keys used by
97     the UI plugin: id, value, label. These are generated from the calls to
98     ``get_item_id``, ``get_item_value`` and ``get_item_label``. If you want to
99     add additional keys you should add them here.
101     The results of ``get_item_label`` is conditionally escaped to prevent
102     Cross Site Scripting (XSS) similar to the templating language.
103     If you know that the content is safe and you want to use these methods
104     to include HTML should mark the content as safe with ``django.utils.safestring.mark_safe``
105     inside the ``get_item_label`` method.
107     ``get_item_id`` and ``get_item_value`` are not escapted by default. These are
108     not a XSS vector with the built-in JS. If you are doing additional formating using
109     these values you should be conscience of this fake and be sure to escape these
110     values.
112     :param item: An item from the search results.
113     :return: A dictionary of information for this item to be sent back to the client.
115 There are also some additional methods that you could want to use/override. These
116 are for more advanced use cases such as using the lookups with JS libraries other
117 than jQuery UI. Most users will not need to override these methods.
119 .. _lookup-format-results:
121 .. py:method:: LookupBase.format_results(self, raw_data, options)
123     Returns a python structure that later gets serialized. This makes a call to
124     :ref:`paginate_results<lookup-paginate-results>` prior to calling
125     :ref:`format_item<lookup-format-item>` on each item in the current page.
127     :param raw_data: The set of all matched results.
128     :param options: Dictionary of ``cleaned_data`` from the lookup form class.
129     :return: A dictionary with two keys ``meta`` and ``data``.
130         The value of ``data`` is an iterable extracted from page_data.
131         The value of ``meta`` is a dictionary. This is a copy of options with one additional element
132         ``more`` which is a translatable "Show more" string
133         (useful for indicating more results on the javascript side).
135 .. _lookup-paginate-results:
137 .. py:method:: LookupBase.paginate_results(results, options)
139     If :ref:`SELECTABLE_MAX_LIMIT` is defined or ``limit`` is passed in request.GET
140     then ``paginate_results`` will return the current page using Django's
141     built in pagination. See the Django docs on
142     `pagination <https://docs.djangoproject.com/en/stable/topics/pagination/>`_
143     for more info.
145     :param results: The set of all matched results.
146     :param options: Dictionary of ``cleaned_data`` from the lookup form class.
147     :return: The current `Page object <https://docs.djangoproject.com/en/stable/topics/pagination/#page-objects>`_
148         of results.
151 .. _ModelLookup:
153 Lookups Based on Models
154 --------------------------------------
156 Perhaps the most common use case is to define a lookup based on a given Django model.
157 For this you can extend ``selectable.base.ModelLookup``. To extend ``ModelLookup`` you
158 should set two class attributes: ``model`` and ``search_fields``.
160     .. code-block:: python
162         from __future__ import unicode_literals
164         from selectable.base import ModelLookup
165         from selectable.registry import registry
167         from .models import Fruit
170         class FruitLookup(ModelLookup):
171             model = Fruit
172             search_fields = ('name__icontains', )
174         registry.register(FruitLookup)
176 The syntax for ``search_fields`` is the same as the Django
177 `field lookup syntax <http://docs.djangoproject.com/en/stable/ref/models/querysets/#field-lookups>`_.
178 Each of these lookups are combined as OR so any one of them matching will return a
179 result. You may optionally define a third class attribute ``filters`` which is a dictionary of
180 filters to be applied to the model queryset. The keys should be a string defining a field lookup
181 and the value should be the value for the field lookup. Filters on the other hand are
182 combined with AND.
185 User Lookup Example
186 --------------------------------------
188 Below is a larger model lookup example using multiple search fields, filters
189 and display options for the `auth.User <https://docs.djangoproject.com/en/stable/topics/auth/#users>`_
190 model.
192     .. code-block:: python
194         from django.contrib.auth.models import User
195         from selectable.base import ModelLookup
196         from selectable.registry import registry
199         class UserLookup(ModelLookup):
200             model = User
201             search_fields = (
202                 'username__icontains',
203                 'first_name__icontains',
204                 'last_name__icontains',
205             )
206             filters = {'is_active': True, }
208             def get_item_value(self, item):
209                 # Display for currently selected item
210                 return item.username
212             def get_item_label(self, item):
213                 # Display for choice listings
214                 return u"%s (%s)" % (item.username, item.get_full_name())
216         registry.register(UserLookup)
219 .. _lookup-decorators:
221 Lookup Decorators
222 --------------------------------------
224 Registering lookups with django-selectable creates a small API for searching the
225 lookup data. While the amount of visible data is small there are times when you want
226 to restrict the set of requests which can view the data. For this purpose there are
227 lookup decorators. To use them you simply decorate your lookup class.
229     .. code-block:: python
231         from django.contrib.auth.models import User
232         from selectable.base import ModelLookup
233         from selectable.decorators import login_required
234         from selectable.registry import registry
237         @login_required
238         class UserLookup(ModelLookup):
239             model = User
240             search_fields = ('username__icontains', )
241             filters = {'is_active': True, }
243         registry.register(UserLookup)
245 .. note::
247     The class decorator syntax was introduced in Python 2.6. If you are using
248     django-selectable with Python 2.5 you can still make use of these decorators
249     by applying the without the decorator syntax.
251     .. code-block:: python
253         class UserLookup(ModelLookup):
254             model = User
255             search_fields = ('username__icontains', )
256             filters = {'is_active': True, }
258         UserLookup = login_required(UserLookup)
260         registry.register(UserLookup)
262 Below are the descriptions of the available lookup decorators.
265 ajax_required
266 ______________________________________
268 The django-selectable javascript will always request the lookup data via
269 XMLHttpRequest (AJAX) request. This decorator enforces that the lookup can only
270 be accessed in this way. If the request is not an AJAX request then it will return
271 a 400 Bad Request response.
274 login_required
275 ______________________________________
277 This decorator requires the user to be authenticated via ``request.user.is_authenticated``.
278 If the user is not authenticated this will return a 401 Unauthorized response.
279 ``request.user`` is set by the ``django.contrib.auth.middleware.AuthenticationMiddleware``
280 which is required for this decorator to work. This middleware is enabled by default.
282 staff_member_required
283 ______________________________________
285 This decorator builds from ``login_required`` and in addition requires that
286 ``request.user.is_staff`` is ``True``. If the user is not authenticatated this will
287 continue to return at 401 response. If the user is authenticated but not a staff member
288 then this will return a 403 Forbidden response.