This documentation is optionnal, but it is complementary with all other documentation. It aims advanced users.
Consider a social network about music. In order to propose all songs in the world in its autocomplete, it should either:
The purpose of this documentation is to describe every elements involved. Note that a living demonstration is available in test_api_project, where one project serves a full database of cities via an API to another.
In test_api_project, of course you should not hardcode urls like that in actual projects:
import autocomplete_light
from cities_light.contrib.autocomplete_light_restframework import RemoteCountryChannel, RemoteCityChannel
from cities_light.models import City, Country
autocomplete_light.register(Country, RemoteCountryChannel,
source_url = 'http://localhost:8000/cities_light/country/')
autocomplete_light.register(City, RemoteCityChannel,
source_url = 'http://localhost:8000/cities_light/city/')
Check out the documentation of RemoteCountryChannel and RemoteCityChannel for more.
Uses an API to propose suggestions from an HTTP API, tested with djangorestframework.
An example implementation usage is demonstrated in the django-cities-light contrib folder.
Autocomplete box display chronology:
Remote result selection chronology:
Set result_template and autocomplete_template if necessary.
Given an url to a remote object, return the corresponding model from the local database.
The default implementation expects url to respond with a JSON dict of the attributes of an object.
For relation attributes, it expect the value to be another url that will respond with a JSON dict of the attributes of the related object.
It calls model_for_source_url() to find which model class corresponds to which url. This allows fetch() to be recursive.
Take a result’s dict representation, return it’s local pk which might have been just created.
If your channel works with 0 to 1 API call, consider overriding this method. If your channel is susceptible of using several different API calls, consider overriding fetch().
Parses JSON from the API, return model instances.
The JSON should contain a list of dicts. Each dict should contain the attributes of an object. Relation attributes should be represented by their url in the API, which is set to model._source_url.
Returns a list of results from both the local database and the API if in the context of a request.
Using self.limit_results and the number of local results, adds results from get_remote_results().
Return an API url for the current autocomplete request.
By default, return self.source_url with the data dict returned by get_source_url_data().
Given a limit of items, return a dict of data to send to the API.
By default, it passes current request GET arguments, along with format: ‘json’ and the limit.
Take an URL from the API this remote channel is supposed to work with, return the model class to use for that url.
It is only needed for the default implementation of fetch(), because it has to follow relations recursively.
Channels with bootstrap=’remote’ get a deck using RemoteChannelDeck’s getValue() rather than the default getValue() function.
var RemoteChannelDeck = {
// The default deck getValue() implementation just returns the PK from the
// result HTML. RemoteChannelDeck's implementation checks for a textarea
// that would contain a JSON dict in the result's HTML. If the dict has a
// 'value' key, then return this value. Otherwise, make a blocking ajax
// request: POST the json dict to the channel url. It expects that the
// response will contain the value.
getValue: function(result) {
data = $.parseJSON(result.find('textarea').html());
if (data.value) return data.value;
var value = false;
$.ajax(this.payload.channel.url, {
async: false,
type: 'post',
data: {
'result': result.find('textarea').html(),
},
success: function(text, jqXHR, textStatus) {
value = text;
}
});
return value;
}
}
$(document).ready(function() {
// Instanciate decks with RemoteChannelDeck as override for all widgets with
// channel 'remote'.
$('.autocomplete_light_widget[data-bootstrap=remote]').each(function() {
$(this).yourlabs_deck(RemoteChannelDeck);
});
});