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:


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



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.

The special value 'all' disables language filtering. This means that objects will be returned once per language in which they match the query, with the appropriate translation loaded.


support for select_related() in combination with language('all') is experimental. Please check the generated queries and open an issue if you have any problem. Feedback is appreciated as well.



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.


This feature requires Django 1.6 or newer.



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

This can be used to target specific translations of specific objects for deletion. For instance:

# Delete English translation of all objects that have field == "foo"

# Delete all translations but English for object with id 42


It is an error to delete all translations of an instance. This will cause the object to be unreachable through translation-aware queries and invisible in the admin panel.

If you delete all translations and re-create one immediately after, remember to enclose the whole process in a transaction to avoid the possibility of leaving the object unreachable.

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

Deprecated since version 1.4.

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.


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


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


Changed in version 0.5.


Deprecated since version 1.4.

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.

This method is now deprecated, and one should use TranslationQueryset.fallbacks() for an equivalent feature.


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.