I am using Hvad to make translatable models but I am getting an error trying to fetch a model.
I have two models classes like these:
class Boy(TranslatableModel):
age = models.PositiveSmallIntegerField()
toy = models.ForeignKey(Toy)
translations = TranslatedFields(
name = models.CharField(max_length=60),
)
class Toy(TranslatableModel):
price = models.PositiveSmallIntegerField()
translations = TranslatedFields(
model_name = models.CharField(max_length=60),
)
I am trying to do make a query like:
Boy = Boy.objects.language('en').filter(name="john", toy__model_name="car")
I am getting the following error: To access translated fields like 'model_name' from an untranslated model, you must use a translation aware manager. For non-translatable models, you can get one using hvad.utils.get_translation_aware_manager. For translatable models, use the language() method.
The following works perfect:
Boy = Boy.objects.language('en').filter(name="john")
So the error is when I add // toy__model_name="car" //
What am I doing wrong? What is the way to achieve what I want?
Answer
The error you're seeing occurs because the field model_name
is part of the Toy
model's translated fields, which are not directly available for filtering without using a translation-aware manager or method. In your query, you are trying to filter on a translated field (model_name
) of a related model (Toy
), but you haven't made the related model (Toy
) translation-aware in the query.
To filter across translated fields from related models, you need to ensure that the related model's translated fields are also considered translation-aware. Here’s how you can modify your query to handle this:
Solution: Use language()
on the related model
You can use language()
to ensure that the related Toy
model is also considered in the correct language context.
Here’s how you can modify your query:
Boy.objects.language('en').filter(name="john", toy__translations__model_name="car")
Explanation:
-
toy__translations__model_name
:- Since
model_name
is a translated field in theToy
model, you need to access it throughtranslations__model_name
. - The
translations
attribute is a manager that handles the translation-related fields, so you need to reference the translated field (model_name
) through it.
- Since
-
language('en')
:- You've already used
.language('en')
on theBoy
model to fetch the English translations forname
, and similarly, by referencing the translated fields ofToy
throughtranslations
, Django knows to fetch the translation ofmodel_name
in the appropriate language.
- You've already used
Full Example Query:
This query will fetch Boy
objects whose translated name
is "john"
and whose related Toy
object's translated model_name
is "car"
in the English language.
Boy.objects.language('en').filter(name="john", toy__translations__model_name="car")
Why the Error Occurred:
- Related model's translated field: In your initial query,
toy__model_name
was incorrectly referring to the untranslatedToy
model field. Sincemodel_name
is a translated field, it requires accessing it through thetranslations
manager. - Translation-awareness: The error message suggests that you need to use translation-aware methods to access translated fields in related models. The
translations
manager onToy
enables that.
Additional Notes:
- If you're doing complex queries with multiple languages and translations, always ensure that any field you are filtering or accessing is wrapped with the
translations
manager when it's a translated field.