4. Queryset API

If you do not need to do fancy things such as custom querysets and are not in the process of optimizing your queries yet, you can skip straight to next section, to start using your translatable models to build some forms.

The queryset API is at the heart of hvad. It provides the ability to filter on translatable fields and retrieve instances along with their translations. They come in two flavors:

Note

It is possible to override the querysets used on a model’s manager.

4.1. TranslationQueryset

The TranslationQueryset works on a translatable model, limiting itself to instances that have a translation in a specific language. Its API is almost identical to the regular Django QuerySet.

New and Changed Methods

language

language(language_code=None)

Sets the language for the queryset to either the given language code or the currently active language if None. Language resolution will be deferred until the query is evaluated.

This filters out all instances that are not translated in the given language, and makes translatable fields available on the query results.

fallbacks

fallbacks(*languages)

New in version 0.6.

Enables fallbacks on the queryset. When the queryset has fallbacks enabled, it will try to use fallback languages if an object has not translation available in the language given to language().

The languages arguments specified the languages to use, priorized from first to last. Special value None will be replaced with current language as returned by get_language(). If called with an empty argument list, the LANGUAGES setting will be used.

If an instance has no translation in the language()-specified language, nor in any of the languages given to fallbacks(), an arbitrary translation will be picked.

Passing the single value None alone will disable fallbacks.

Note

This feature requires Django 1.6 or newer.

delete_translations

delete_translations()

Deletes all Translations Model instances in a queryset, without deleting the Shared Model instances.

Not implemented public queryset methods

The following are methods on a queryset which are public APIs in Django, but are not implemented (yet) in django-hvad:

Using any of these methods will raise a NotImplementedError.

Performance consideration

While most methods on TranslationQueryset run using the same amount of queries as if they were untranslated, they all do slightly more complex queries (one extra join).

The following methods run two queries where standard querysets would run one:

  • create()
  • update() (only if both translated and untranslated fields are updated at once)

get_or_create() runs one query if the object exists, three queries if the object does not exist in this language, but in another language and four queries if the object does not exist at all. It will return True for created if either the shared or translated instance was created.

4.2. FallbackQueryset

This is a queryset returned by untranslated(), which can be used both to get the untranslated parts of models only or to use fallbacks for loading a translation based on a priority list of languages. By default, only the untranslated parts of models are retrieved from the database, and accessing translated field will trigger an additional query for each instance.

Warning

You may not use any translated fields in any method on this queryset class.

Warning

If you have a default ordering defined on your model and it includes any translated field, you must specify an ordering on every query so as not to use the translated fields specified by the default ordering.

New Methods

use_fallbacks

Changed in version 0.5.

use_fallbacks(*fallbacks)

Returns a queryset which will use fallbacks to get the translated part of the instances returned by this queryset. If fallbacks is given as a tuple of language codes, it will try to get the translations in the order specified, replacing the special None value with the current language at query evaluation, as returned by get_language(). Otherwise the order of your LANGUAGES setting will be used, prepended with current language.

Warning

Using fallbacks with a version of Django older than 1.6 will cause a lot of queries! In the worst case 1 + (n * x) with n being the amount of rows being fetched and x the amount of languages given as fallbacks. Only ever use this method when absolutely necessary and on a queryset with as few results as possible.

Changed in version 0.5: Fallbacks were reworked, so that when running on Django 1.6 or newer, only one query is needed.

Not implemented public queryset methods

The following are methods on a queryset which are public APIs in Django, but are not implemented on fallback querysets.


Next, we will use our models and queries to build some forms.