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:
- The TranslationQueryset, for working with
instances translated in a specific language. It is the one used when calling
TranslationManager.language()
. - The FallbackQueryset, for working with
all instances regardless of their language, and eventually loading translations
using a fallback algorithm. It is the one used when calling
TranslationManager.untranslated()
.
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.
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.Note
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.
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, theLANGUAGES
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 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" MyModel.objects.language('en').filter(field='foo').delete_translations() # Delete all translations but English for object with id 42 MyModel.objects.language('all').exclude(language_code='en').filter(pk=42).delete_translations()
Warning
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:
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.
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)¶ 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 byget_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.
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.