File: compatibility.rst

package info (click to toggle)
python-django-parler 2.3-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,032 kB
  • sloc: python: 4,293; makefile: 164; sh: 6
file content (104 lines) | stat: -rw-r--r-- 3,620 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
Django compatibility
====================

This package has been tested with:

* Django versions 2.2 up to 4.0
* Python versions 3.6 and up

See the `the tox.ini file <https://github.com/django-parler/django-parler/blob/master/tox.ini>`_
for the compatibility testing matrix.

.. _orm-restrictions:

Using multiple ``filter()`` calls
---------------------------------

Since translated fields live in a separate model,
they can be filtered like any normal relation::

    object = MyObject.objects.filter(translations__title='cheese omelet')

    translation1 = myobject.translations.all()[0]

However, if you have to query a language or translated attribute, this should happen in a single query.
That can either be a single
:func:`~django.db.models.query.QuerySet.filter`,
:func:`~parler.managers.TranslatableManager.translated` or
:func:`~parler.managers.TranslatableManager.active_translations`) call::

    from parler.utils import get_active_language_choices

    MyObject.objects.filter(
        translations__language_code__in=get_active_language_choices(),
        translations__slug='omelette'
    )

Queries on translated fields, even just ``.translated()`` spans a relationship.
Hence, they can't be combined with other filters on translated fields,
as that causes double joins on the translations table.
See `the ORM documentation <https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships>`_ for more details.

.. _ordering:

The ``ordering`` meta field
---------------------------

It's not possible to order on translated fields by default.
Django won't allow the following::

    from django.db import models
    from parler.models import TranslatableModel, TranslatedFields

    class MyModel(TranslatableModel):
        translations = TranslatedFields(
            title = models.CharField(max_length=100),
        )

        class Meta:
            ordering = ('title',)  # NOT ALLOWED

        def __unicode__(self):
            return self.title

You can however, perform ordering within the queryset::

    MyModel.objects.translated('en').order_by('translations__title')

You can also use the provided classes to perform the sorting within Python code.

* For the admin :attr:`~django.contrib.admin.ModelAdmin.list_filter` use: :class:`~parler.admin.SortedRelatedFieldListFilter`
* For forms widgets use: :class:`~parler.widgets.SortedSelect`, :class:`~parler.widgets.SortedSelectMultiple`, :class:`~parler.widgets.SortedCheckboxSelectMultiple`


.. _admin-compat:

Using ``search_fields`` in the admin
------------------------------------

When translated fields are included in the :attr:`~django.contrib.admin.ModelAdmin.search_fields`,
they should be includes with their full ORM path. For example::

    from parler.admin import TranslatableAdmin

    class MyModelAdmin(TranslatableAdmin):
        search_fields = ('translations__title',)


Using ``prepopulated_fields`` in the admin
------------------------------------------

Using :attr:`~django.contrib.admin.ModelAdmin.prepopulated_fields` doesn't work yet,
as the admin will complain that the field does not exist.
Use :func:`~django.contrib.admin.ModelAdmin.get_prepopulated_fields` as workaround::

    from parler.admin import TranslatableAdmin

    class MyModelAdmin(TranslatableAdmin):

        def get_prepopulated_fields(self, request, obj=None):
            # can't use `prepopulated_fields = ..` because it breaks the admin validation
            # for translated fields. This is the official django-parler workaround.
            return {
                'slug': ('title',)
            }