### Set up development environment Source: https://github.com/django-parler/django-parler/blob/master/README.rst Commands to create a virtual environment, activate it, and install the package with tox for development. ```bash python -m venv venv source venv/bin/activate pip install -e . tox ``` -------------------------------- ### Install django-parler Source: https://github.com/django-parler/django-parler/blob/master/README.rst Install the package using pip. ```bash pip install django-parler ``` -------------------------------- ### Build and Test Commands Source: https://github.com/django-parler/django-parler/blob/master/CLAUDE.md Commands for installing, testing, measuring coverage, running tox, formatting, and building docs for django-parler. ```bash # Install in editable mode with test extras pip install -e .[tests] # Run all tests python runtests.py # Run tests for a specific app python runtests.py parler python runtests.py article # Coverage coverage run --rcfile=.coveragerc runtests.py && coverage report # Full tox matrix (Python 3.10-3.13 × Django 5.1-6.0) tox # Format black . && isort . # Build docs cd docs && make html ``` -------------------------------- ### Project Directory Structure Source: https://github.com/django-parler/django-parler/blob/master/CLAUDE.md Tree view of the django-parler repository layout, showing main package, tests, example project, and test runner. ```text parler/ ← Main package (all production code lives here) models.py ← TranslatableModel, TranslatedFields, TranslatedFieldsModel managers.py ← TranslatableManager + QuerySet fields.py ← TranslatedField descriptor cache.py ← Translation caching layer admin.py ← TranslatableAdmin, language tab UI forms.py ← TranslatableModelForm views.py ← View mixins widgets.py ← Admin/form widgets signals.py ← pre/post_translation_save signals appsettings.py ← All PARLER_* settings with defaults utils/ ← Language helpers (compat, conf, context, i18n, template, views) templatetags/ ← parler_tags.py tests/ testapp/ ← Minimal Django app used only in tests test_*.py ← Test modules per concern (admin, cache, forms, managers, query_count, …) example/ ← Working Django project with `article` + `theme1` apps + manage.py runtests.py ← Test runner (configures in-memory SQLite Django project, site_id=4) ``` -------------------------------- ### Using SortedSelect in a ModelForm Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.widgets.rst Example of integrating SortedSelect into a Django ModelForm to ensure translated choices are sorted. ```python from django import forms from parler.widgets import SortedSelect class MyModelForm(forms.ModelForm): class Meta: # Make sure translated choices are sorted. model = MyModel widgets = { 'preferred_language': SortedSelect, 'country': SortedSelect, } ``` -------------------------------- ### Ordering meta field not allowed Source: https://github.com/django-parler/django-parler/blob/master/docs/compatibility.rst Shows that ordering by translated fields in Meta is not allowed. The example includes a TranslatableModel with a translated title field and a Meta ordering that will fail. ```python 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 ``` -------------------------------- ### Query a specific translated field with safe_translation_getter Source: https://github.com/django-parler/django-parler/blob/master/README.rst Use the safe_translation_getter method to retrieve a specific translated field value for a given language code. This example gets the 'title' field in French ('fr'). ```python model.safe_translation_getter('title', language_code='fr') ``` -------------------------------- ### Build documentation with tox Source: https://github.com/django-parler/django-parler/blob/master/README.rst Commands to build the documentation and open the generated HTML index file. ```bash tox -e docs open .tox/docs/tmp/html/index.html ``` -------------------------------- ### Combine TranslatableModel with PolymorphicModel using custom manager and default manager Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/polymorphicmodel.rst Defines a base Product model and concrete Book and Pen models. Book uses a custom BookManager (Solution 1) to combine managers, while Pen overrides default_manager with TranslatableManager (Solution 2). ```python from django.db import models from django.utils.encoding import force_text from parler.models import TranslatableModel, TranslatedFields from parler.managers import TranslatableManager from polymorphic import PolymorphicModel from .managers import BookManager class Product(PolymorphicModel): # The shared base model. Either place translated fields here, # or place them at the subclasses (see note below). code = models.CharField(blank=False, default='', max_length=16) price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) class Book(Product, TranslatableModel): # Solution 1: use a custom manager that combines both. objects = BookManager() translations = TranslatedFields( name=models.CharField(blank=False, default='', max_length=128), slug=models.SlugField(blank=False, default='', max_length=128) ) def __str__(self): return force_text(self.code) class Pen(Product, TranslatableModel): # Solution 2: override the default manager. default_manager = TranslatableManager() translations = TranslatedFields( identifier=models.CharField(blank=False, default='', max_length=255) ) def __str__(self): return force_text(self.identifier) ``` -------------------------------- ### Using SortedRelatedFieldListFilter in ModelAdmin Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.admin.rst Example of configuring a list_filter in a Django ModelAdmin to use SortedRelatedFieldListFilter for sorting translated model fields. ```python from django.contrib import admin from parler.admin import SortedRelatedFieldListFilter class MyAdmin(admin.ModelAdmin): list_filter = ( ('related_field_name', SortedRelatedFieldListFilter), ) ``` -------------------------------- ### Run tests with tox Source: https://github.com/django-parler/django-parler/blob/master/README.rst Command to run the test suite for Python 3.13 and Django 5.2 using tox. ```bash tox -e py313-django52 ``` -------------------------------- ### Use switch_language Context Manager Source: https://github.com/django-parler/django-parler/blob/master/README.rst Use the context manager to temporarily change the language. ```python from parler.utils.context import switch_language ``` -------------------------------- ### Explicitly defining TranslatedField in a model Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.fields.rst This example demonstrates how to manually add TranslatedField to a TranslatableModel, including the use of the any_language=True option for fallback support. ```python from django.db import models from parler.models import TranslatableModel, TranslatedFieldsModel class MyModel(TranslatableModel): title = TranslatedField(any_language=True) # Add with any-fallback support slug = TranslatedField() # Optional, but explicitly mentioned class MyModelTranslation(TranslatedFieldsModel): # Manual model class: master = models.ForeignKey(MyModel, related_name='translations', null=True) title = models.CharField("Title", max_length=200) slug = models.SlugField("Slug") ``` -------------------------------- ### Configure INSTALLED_APPS Source: https://github.com/django-parler/django-parler/blob/master/README.rst Add the parler app to your Django project settings. ```python INSTALLED_APPS += ( 'parler', ) ``` -------------------------------- ### Switch language with switch_language context manager Source: https://github.com/django-parler/django-parler/blob/master/README.rst Use the switch_language context manager to temporarily switch the active language for a model instance. In this example, the title is printed in French ('fr'). ```python with switch_language(model, 'fr'): print model.title ``` -------------------------------- ### Forking language settings with add_default_language_settings Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/custom-settings.rst Use this pattern to define custom language settings by wrapping the default parler configuration. ```default from django.conf import settings from parler import appsettings as parler_appsettings from parler.utils import normalize_language_code, is_supported_django_language from parler.utils.conf import add_default_language_settings MYCMS_DEFAULT_LANGUAGE_CODE = getattr(settings, 'MYCMS_DEFAULT_LANGUAGE_CODE', FLUENT_DEFAULT_LANGUAGE_CODE) MYCMS_LANGUAGES = getattr(settings, 'MYCMS_LANGUAGES', parler_appsettings.PARLER_LANGUAGES) MYCMS_DEFAULT_LANGUAGE_CODE = normalize_language_code(MYCMS_DEFAULT_LANGUAGE_CODE) MYCMS_LANGUAGES = add_default_language_settings( MYCMS_LANGUAGES, 'MYCMS_LANGUAGES', hide_untranslated=False, hide_untranslated_menu_items=False, code=MYCMS_DEFAULT_LANGUAGE_CODE, fallbacks=[MYCMS_DEFAULT_LANGUAGE_CODE] ) ``` -------------------------------- ### Implement TranslatableAdmin with MPTTModelAdmin Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/mptt.rst Merge base classes in the admin interface to support translatable MPTT models. ```python from django.contrib import admin from parler.admin import TranslatableAdmin, TranslatableModelForm from mptt.admin import MPTTModelAdmin from mptt.forms import MPTTAdminForm from .models import Category class CategoryAdminForm(MPTTAdminForm, TranslatableModelForm): pass class CategoryAdmin(TranslatableAdmin, MPTTModelAdmin): form = CategoryAdminForm def get_prepopulated_fields(self, request, obj=None): return {'slug': ('title',)} # needed for translated fields admin.site.register(Category, CategoryAdmin) ``` -------------------------------- ### Declare translated fields with TranslatedField Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.forms.rst Shows how to declare translated fields on a TranslatableModelForm using the TranslatedField wrapper. The example includes optional configuration for a field with a custom form_class and widget. ```python class MyForm(TranslatableModelForm): title = TranslatedField() slug = TranslatedField() description = TranslatedField(form_class=forms.CharField, widget=TinyMCE) ``` -------------------------------- ### Create empty data migration Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/migrating.rst Command to create an empty migration for the data migration. ```default manage.py makemigrations --empty myapp --name "migrate_translatable_fields" ``` -------------------------------- ### BaseTranslatableAdmin Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.admin.rst This class provides shared code between regular model admin and inline classes. It includes methods for getting the form language, language tabs, queryset, and the form to use for the model. ```APIDOC ## class parler.admin.BaseTranslatableAdmin ### Description Shared code between the regular model admin and inline classes. Provides methods to handle the current language for forms and querysets. ### Form - **form** (_TranslatableModelForm_) - The form to use for the model. Alias of `TranslatableModelForm`. ### Methods - **get_form_language(request, obj=None)** - Return the current language for the currently displayed object fields. - **get_language_tabs(request, obj, available_languages, css_class=None)** - Determine the language tabs to show. - **get_queryset(request)** - Make sure the current language is selected. - **get_queryset_language(request)** - Return the language to use in the queryset. - **query_language_key** = 'language' - The URL parameter for the language value. ``` -------------------------------- ### Use switch_language to render an object in a different language Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.context.rst Use switch_language to temporarily switch both the translation language and the object language. This example renders the object's title in Dutch. It is not thread-safe when the object is shared between threads. ```python with switch_language(object, 'nl'): print object.title ``` -------------------------------- ### Create a proxy model with translated fields Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/existing.rst Create a proxy class that inherits from the existing model and TranslatableModel, then add a translations field using TranslatedFields. This allows adding translated fields to an existing model without modifying the original. ```python from django.contrib.sites.models import Site from parler.models import TranslatableModel, TranslatedFields class TranslatableSite(TranslatableModel, Site): class Meta: proxy = True translations = TranslatedFields() ``` -------------------------------- ### Manual translation model definition Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/manual-models.rst Define a translatable model with a TranslatedField and a corresponding TranslatedFieldsModel subclass. The translation model links to the master model via a ForeignKey with related_name='translations' and uses unique_together on ('language_code', 'master'). This manual setup allows overriding methods like save(). ```python from django.db import models from parler.models import TranslatableModel, TranslatedFieldsModel from parler.fields import TranslatedField class MyModel(TranslatableModel): title = TranslatedField() # Optional, explicitly mention the field class Meta: verbose_name = _("MyModel") def __unicode__(self): return self.title class MyModelTranslation(TranslatedFieldsModel): master = models.ForeignKey(MyModel, related_name='translations', null=True) title = models.CharField(_("Title"), max_length=200) class Meta: unique_together = ('language_code', 'master') verbose_name = _("MyModel translation") ``` -------------------------------- ### LanguagesSetting.get_first_language(site_id=None) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.conf.rst Returns the first language for the current site. This can be used for user interfaces where languages are displayed in tabs. ```APIDOC ## LanguagesSetting.get_first_language(site_id=None) ### Description Returns the first language for the current site. This can be used for user interfaces where languages are displayed in tabs. ### Method Method: get_first_language ### Parameters - **site_id** (optional) - The site ID to use. ### Returns The first language code. ``` -------------------------------- ### Accessing language settings methods Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/custom-settings.rst Methods available on the language settings object after processing with add_default_language_settings. ```default MYCMS_LANGUAGES.get_language() MYCMS_LANGUAGES.get_active_choices() MYCMS_LANGUAGES.get_fallback_languages() MYCMS_LANGUAGES.get_default_language() MYCMS_LANGUAGES.get_first_language() ``` -------------------------------- ### Create translation model migration Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/migrating.rst Command to create the migration that adds the translation model. ```default manage.py makemigrations myapp --name "add_translation_model" ``` -------------------------------- ### Create custom language settings with add_default_language_settings Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.conf.rst Shows how to create a custom variation of PARLER_LANGUAGES with extra fields using add_default_language_settings(). It imports settings and parler_appsettings, reads optional overrides, and applies defaults like code, fallback, and hide_untranslated. ```python from django.conf import settings from parler import appsettings as parler_appsettings # Create local names, which are based on the global parler settings MYAPP_DEFAULT_LANGUAGE_CODE = getattr(settings, 'MYAPP_DEFAULT_LANGUAGE_CODE', parler_appsettings.PARLER_DEFAULT_LANGUAGE_CODE) MYAPP_LANGUAGES = getattr(settings, 'MYAPP_LANGUAGES', parler_appsettings.PARLER_LANGUAGES) # Apply the defaults to the languages MYAPP_LANGUAGES = parler_appsettings.add_default_language_settings(MYAPP_LANGUAGES, 'MYAPP_LANGUAGES', code=MYAPP_DEFAULT_LANGUAGE_CODE, fallback=MYAPP_DEFAULT_LANGUAGE_CODE, hide_untranslated=False ) ``` -------------------------------- ### Create Translatable Models Source: https://github.com/django-parler/django-parler/blob/master/README.rst Use the TranslatedFields wrapper to mark model fields as translatable. ```python from django.db import models from parler.models import TranslatableModel, TranslatedFields class MyModel(TranslatableModel): translations = TranslatedFields( title = models.CharField(_("Title"), max_length=200) ) def __unicode__(self): return self.title ``` -------------------------------- ### Configure Django cache backend for django-parler Source: https://github.com/django-parler/django-parler/blob/master/docs/performance.rst Set up a Django cache backend (e.g., Memcached) to enable default caching of translated content. The KEY_PREFIX should be changed per project. Requires the python-memcached package. ```python CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'KEY_PREFIX': 'mysite.production', # Change this 'LOCATION': '127.0.0.1:11211', 'TIMEOUT': 24*3600 }, } ``` ```default pip install python-memcached ``` -------------------------------- ### Admin prepopulated_fields workaround with get_prepopulated_fields Source: https://github.com/django-parler/django-parler/blob/master/docs/compatibility.rst Workaround for prepopulated_fields not working with translated fields. Override get_prepopulated_fields to return the mapping, as the admin validation fails otherwise. ```python 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',) } ``` -------------------------------- ### Update admin to use the proxy model Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/existing.rst Register the new proxy model with a custom admin class that combines TranslatableAdmin and the original SiteAdmin. Unregister the original Site model first to avoid conflicts. ```python from django.contrib.sites.admin import SiteAdmin from django.contrib.sites.models import Site from parler.admin import TranslatableAdmin, TranslatableStackedInline class NewSiteAdmin(TranslatableAdmin, SiteAdmin): pass admin.site.unregister(Site) admin.site.register(TranslatableSite, NewSiteAdmin) ``` -------------------------------- ### Create a TranslatableAdmin for a project model Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.admin.rst Shows how to integrate django-parler into Django admin by subclassing TranslatableAdmin and registering a model. Translated fields can be used in list_display and fieldsets like normal fields. ```python from django.contrib import admin from parler.admin import TranslatableAdmin from myapp.models import Project class ProjectAdmin(TranslatableAdmin): list_display = ('title', 'status') fieldsets = ( (None, { 'fields': ('title', 'status'), }), ) admin.site.register(Project, ProjectAdmin) ``` -------------------------------- ### Create migration to remove old fields Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/migrating.rst Command to create the migration that removes the original field. ```default manage.py makemigrations myapp --name "remove_untranslated_fields" ``` -------------------------------- ### TranslatableQuerySet.create(**kwargs) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.managers.rst Create a new object with the given kwargs, saving it to the database and returning the created object. ```APIDOC ## TranslatableQuerySet.create(**kwargs) ### Description Create a new object with the given kwargs, saving it to the database and returning the created object. ### Method create ### Signature `create(**kwargs)` ### Parameters - **kwargs** - Required - Field values for the new object. ### Returns The created object. ``` -------------------------------- ### Define TranslatedFields with Meta options Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.models.rst Pass a dictionary of Meta options to the TranslatedFields constructor, such as database constraints. ```python class MyModel(TranslatableModel): translations = TranslatedFields( title = models.CharField("Title", max_length=200), slug = models.SlugField("Slug"), meta = {'constraints': [models.UniqueConstraint(fields=['language_code', 'slug'], name='mymodel_translation_uniq_lang_slug')]}, ) ``` -------------------------------- ### parler.is_multilingual_project(site_id=None) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.rst Checks whether the current Django project is configured for multilingual support. Optionally accepts a site_id parameter. ```APIDOC ## parler.is_multilingual_project(site_id=None) ### Description Checks whether the current Django project is configured for multilingual support. ### Method Function ### Signature `parler.is_multilingual_project(site_id=None)` ### Parameters - **site_id** (optional) - The site ID to check. If not provided, the current site is used. ### Returns - **bool** - True if the project is multilingual, False otherwise. ### Example ```python from parler import is_multilingual_project if is_multilingual_project(): print("Project supports multiple languages") else: print("Project is not multilingual") ``` ``` -------------------------------- ### post_translation_init Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.signals.rst Signal sent after a translated model has been initialized, similar to Django's post_init signal. ```APIDOC ## Signal: post_translation_init ### Description Called when the translated model has been initialized, similar to Django's `post_init` signal. ### Signal Name `parler.signals.post_translation_init` ### Arguments - **sender** (model class) - The model class that just had an instance created. - **instance** (translated model) - The actual translated model that's just been created. ``` -------------------------------- ### LanguagesSetting.get_active_choices(language_code=None, site_id=None) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.conf.rst Finds out which translations should be visible in the site. Returns a list with either a single choice (the current language) or a list with the current language plus fallback language. ```APIDOC ## LanguagesSetting.get_active_choices(language_code=None, site_id=None) ### Description Finds out which translations should be visible in the site. Returns a list with either a single choice (the current language) or a list with the current language plus fallback language. ### Method Method: get_active_choices ### Parameters - **language_code** (optional) - The language code to check. - **site_id** (optional) - The site ID to use. ### Returns A list of language codes that should be visible. ``` -------------------------------- ### TranslatableAdmin as first inherited class Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/guardian.rst When TranslatableAdmin is the first inherited class, the admin class definition is shown. A template inheriting the guardian change form is needed to display both guardian and parler content. ```python class ProjectAdmin(TranslatableAdmin, GuardedModelAdmin): pass ``` ```html+django {% extends "admin/guardian/model/change_form.html" %} ``` -------------------------------- ### TranslatedField.__init__(any_language=False) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.fields.rst Initializes a TranslatedField instance. The any_language parameter, when True, causes the attribute to always return a translated value even if the current language and fallback are missing. ```APIDOC ## TranslatedField.__init__(any_language=False) ### Description Initializes a TranslatedField instance. The any_language parameter, when True, causes the attribute to always return a translated value even if the current language and fallback are missing. ### Method Constructor ### Parameters - **any_language** (bool) - Optional - When True, the field always returns a translated value, even if the current language and fallback are missing. ### Example ```python from django.db import models from parler.models import TranslatableModel, TranslatedFieldsModel class MyModel(TranslatableModel): title = TranslatedField(any_language=True) # Add with any-fallback support slug = TranslatedField() # Optional, but explicitly mentioned class MyModelTranslation(TranslatedFieldsModel): # Manual model class: master = models.ForeignKey(MyModel, related_name='translations', null=True) title = models.CharField("Title", max_length=200) slug = models.SlugField("Slug") ``` ``` -------------------------------- ### Configure PARLER_LANGUAGES Source: https://github.com/django-parler/django-parler/blob/master/README.rst Configure the admin tabs and fallback behavior for translations. ```python PARLER_LANGUAGES = { None: ( {'code': 'en',}, {'code': 'en-us',}, {'code': 'it',}, {'code': 'nl',}, ), 'default': { 'fallback': 'en', # defaults to PARLER_DEFAULT_LANGUAGE_CODE 'hide_untranslated': False, # the default; let .active_translations() return fallbacks too. } } ``` -------------------------------- ### Configure PARLER_LANGUAGES for admin tabs Source: https://github.com/django-parler/django-parler/blob/master/docs/quickstart.rst Configure the language tabs for the admin interface. Replace None with SITE_ID for multi-site projects. The 'default' key sets fallbacks and hide_untranslated behavior. ```default PARLER_LANGUAGES = { None: ( {'code': 'en',}, {'code': 'en-us',}, {'code': 'it',}, {'code': 'nl',}, ), 'default': { 'fallbacks': ['en'], # defaults to PARLER_DEFAULT_LANGUAGE_CODE 'hide_untranslated': False, # the default; let .active_translations() return fallbacks too. } } ``` -------------------------------- ### pre_translation_init Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.signals.rst Signal sent when a translated model is initialized, similar to Django's pre_init signal. ```APIDOC ## Signal: pre_translation_init ### Description Called when the translated model is initialized, similar to Django's `pre_init` signal. ### Signal Name `parler.signals.pre_translation_init` ### Arguments - **sender** (model class) - The model class that just had an instance created. - **instance** (translated model) - The actual translated model that's just been created. - **args** (tuple) - Any arguments passed to the model. - **kwargs** (dict) - Any keyword arguments passed to the model. ``` -------------------------------- ### Admin for polymorphic models with translatable fields Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/polymorphicmodel.rst Registers admin classes that inherit from TranslatableAdmin and PolymorphicChildModelAdmin for each child model, and a PolymorphicParentModelAdmin for the base model. Uses TranslatableModelForm as base_form and sets child_models in the parent admin. ```python from django.contrib import admin from parler.admin import TranslatableAdmin, TranslatableModelForm from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin from .models import BaseProduct, Book, Pen class BookAdmin(TranslatableAdmin, PolymorphicChildModelAdmin): base_form = TranslatableModelForm base_model = BaseProduct base_fields = ('code', 'price', 'name', 'slug') class PenAdmin(TranslatableAdmin, PolymorphicChildModelAdmin): base_form = TranslatableModelForm base_model = BaseProduct base_fields = ('code', 'price', 'identifier',) class BaseProductAdmin(PolymorphicParentModelAdmin): base_model = BaseProduct child_models = ((Book, BookAdmin), (Pen, PenAdmin),) list_display = ('code', 'price',) admin.site.register(BaseProduct, BaseProductAdmin) ``` -------------------------------- ### LanguagesSetting.get_fallback_language(language_code=None, site_id=None) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.conf.rst Finds out what the fallback language is for a given language choice. Deprecated since version 1.5; use get_fallback_languages() instead. ```APIDOC ## LanguagesSetting.get_fallback_language(language_code=None, site_id=None) ### Description Finds out what the fallback language is for a given language choice. Deprecated since version 1.5; use get_fallback_languages() instead. ### Method Method: get_fallback_language ### Parameters - **language_code** (optional) - The language code to check. - **site_id** (optional) - The site ID to use. ### Returns The fallback language code. ``` -------------------------------- ### LanguagesSetting.get_fallback_languages(language_code=None, site_id=None) Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.conf.rst Finds out what the fallback language is for a given language choice. Added in version 1.5. ```APIDOC ## LanguagesSetting.get_fallback_languages(language_code=None, site_id=None) ### Description Finds out what the fallback language is for a given language choice. Added in version 1.5. ### Method Method: get_fallback_languages ### Parameters - **language_code** (optional) - The language code to check. - **site_id** (optional) - The site ID to use. ### Returns The fallback language code. ``` -------------------------------- ### Use smart_override to reverse a URL with current language Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.utils.context.rst Use smart_override to avoid switching language when no change is needed. This ensures URLs wrapped in i18n_patterns receive the correct language code prefix. For URLs with translated fields like a slug, use switch_language instead. ```python with smart_override(self.get_current_language()): return reverse('myobject-details', args=(self.id,)) ``` -------------------------------- ### TranslatableSlugMixin with DetailView Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/slugs.rst Use this mixin with Django's DetailView to handle translatable slugs. It ensures the object is fetched in the proper translation, reads the slug from the translation model, handles fallback languages, and redirects to the translated slug instead of displaying fallback slugs. ```python class ArticleDetailView(TranslatableSlugMixin, DetailView): model = Article template_name = 'article/details.html' ``` -------------------------------- ### Combine TranslatableManager and TreeManager Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/mptt.rst Combine managers and querysets by inheriting from TranslatableQuerySet/TreeQuerySet and TranslatableManager/TreeManager. ```python from parler.managers import TranslatableManager, TranslatableQuerySet from mptt.managers import TreeManager from mptt.querysets import TreeQuerySet class CategoryQuerySet(TranslatableQuerySet, TreeQuerySet): def as_manager(cls): # make sure creating managers from querysets works. manager = CategoryManager.from_queryset(cls)() manager._built_with_as_manager = True return manager as_manager.queryset_only = True as_manager = classmethod(as_manager) class CategoryManager(TreeManager, TranslatableManager): _queryset_class = CategoryQuerySet ``` -------------------------------- ### Ordering within queryset using translated() Source: https://github.com/django-parler/django-parler/blob/master/docs/compatibility.rst Shows how to order by translated fields within a queryset using the translated() method and order_by on the translations relation. ```python MyModel.objects.translated('en').order_by('translations__title') ``` -------------------------------- ### Define TranslatableModel with manual TranslatedFieldsModel Source: https://github.com/django-parler/django-parler/blob/master/docs/api/parler.models.rst Manually create a translation model by inheriting from TranslatedFieldsModel, allowing for custom methods or save() overrides. ```python from django.db import models from parler.models import TranslatableModel, TranslatedFieldsModel from parler.fields import TranslatedField class MyModel(TranslatableModel): title = TranslatedField() # Optional, explicitly mention the field class Meta: verbose_name = _("MyModel") def __str__(self): return self.title class MyModelTranslation(TranslatedFieldsModel): master = models.ForeignKey(MyModel, related_name='translations', null=True) title = models.CharField(_("Title"), max_length=200) class Meta: verbose_name = _("MyModel translation") ``` -------------------------------- ### Original model definition Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/migrating.rst Initial model with a non-translatable field before making it translatable. ```default class MyModel(models.Model): name = models.CharField(max_length=123) ``` -------------------------------- ### Model with translatable fields Source: https://github.com/django-parler/django-parler/blob/master/docs/advanced/migrating.rst Model after adding the translatable fields and the translations descriptor. ```default class MyModel(TranslatableModel): name = models.CharField(max_length=123) translations = TranslatedFields( name=models.CharField(max_length=123), ) ```