Search code examples
pythondjangodjango-modelsdjango-i18ndjango-filters

Python: How to join an operator?


I'm currently developing a Django application with i18n support. This works by providing a field for each language for a given field.

Example model:

class Article(models.Model):
    title_en = models.CharField()
    title_de = models.CharField()
    title_fr = models.CharField()

    # etc...

(under the hood this is automatically done using django-translated-fields)

I would now like to filter for Articles with a given title. The title should be checked in every available language. (so in this case title_en, title_de and title_fr).

If there was only one title, I could query like this:

Article.objects.filter(title=my_title)

I don't want to use this:

Article.objects.filter(Q(title_en=my_title) | Q(title_de=my_title) | Q(title_fr=my_title))

since the fields are created dynamically and the available languages could change.

My question

I need to somehow join classes using the __union__ operator.

I came up with this:

Article.objects.filter(*[
    Q(**{
        f"name_{code}": my_name
    })
    for code in available_languages
])

but the joining is missing.

Is there any method to do this? Or is there a better method available to filter for the names?


Solution

  • If you have a list of available languages, you can work with:

    available_languages = ['en', 'de', 'fr']
    
    q_filter = Q(
        *[Q((f'title_{code}', my_title)) for code in available_languages],
        _connector=Q.OR
    )
    
    Article.objects.filter(q_filter)