django-localized-fields
is an implementation of a field class for Django models that allows the field's value to be set in multiple languages. It does this by utilizing the hstore
type (PostgreSQL specific), which is available as models.HStoreField
in Django 1.10.
This package requires Python 3.5 or newer and Django 1.10 or newer.
We're working on making this easier to setup and use. Any feedback is apreciated. Here's a short list of things we're working to improve:
- Make it unnecesarry to add anything to your INSTALLED_APPS.
- Make it unnecesarry to modify your migrations manually to enable the PostgreSQL HStore extension.
Install the package from PyPi:
$ pip install django-localized-fields
Add
localized_fields
anddjango.contrib.postgres
to yourINSTALLED_APPS
:INSTALLED_APPS = [ .... 'django.contrib.postgres', 'localized_fields' ]
Set
LANGUAGES` and `LANGUAGE_CODE
in your settings:LANGUAGE_CODE = 'en' # default language LANGUAGES = ( ('en', 'English'), ('nl', 'Dutch'), ('ro', 'Romanian') )
Declare fields on your model as LocalizedField
:
from localized_fields.fields import LocalizedField
class MyModel(models.Model):
title = LocalizedField()
Create your migrations using python manage.py makemigrations
. Open the generated migration in your favorite editor and setup the HStore extension before the first CreateModel
or AddField
operation by adding a migration with the HStoreExtension operation. For example:
from django.contrib.postgres.operations import HStoreExtension
class Migration(migrations.Migration):
...
operations = [
HStoreExtension(),
...
]
Then apply the migration using python manage.py migrate
.
django-localized-fields
integrates with Django's i18n system, in order for certain languages to be available you have to correctly configure the LANGUAGES
and LANGUAGE_CODE
settings:
LANGUAGE_CODE = 'en' # default language
LANGUAGES = (
('en', 'English'),
('nl', 'Dutch'),
('ro', 'Romanian')
)
new = MyModel()
new.title.en = 'english title'
new.title.nl = 'dutch title'
new.title.ro = 'romanian title'
new.save()
By changing the active language you can control which language is presented:
from django.utils import translation
translation.activate('nl')
print(new.title) # prints 'dutch title'
translation.activate('en')
print(new.title) # prints 'english title'
Or get it in a specific language:
print(new.title.get('en')) # prints 'english title'
print(new.title.get('ro')) # prints 'romanian title'
print(new.title.get()) # whatever language is the primary one
You can also explicitly set a value in a certain language:
new.title.set('en', 'other english title')
new.title.set('nl', 'other dutch title')
new.title.ro = 'other romanian title'
Or set a value for current active language:
translation.activate('nl')
new.title = 'other dutch title'
translation.activate('en')
new.title = 'other english title'
new.save()
By default, the following constraints apply to a LocalizedField
:
- Only the default language is
required
. The other languages are optional and can beNULL
. - If
null=True
is specified on theLocalizedField
, then none of the languages are required.
At the moment it is not possible to specifically instruct LocalizedField
to mark certain languages as required or optional.
Besides LocalizedField
, there's also:
LocalizedAutoSlugField
- Automatically creates a slug for every language from the specified field. Depends upon:
- django-autoslug
Currently only supports populate_from. Example usage:
from localized_fields.fields import (LocalizedField, LocalizedAutoSlugField) class MyModel(models.Model): title = LocalizedField() slug = LocalizedAutoSlugField(populate_from='title')
LocalizedBleachField
- Automatically bleaches the content of the field.
- django-bleach
Example usage:
from localized_fields.fields import (LocalizedField, LocalizedBleachField) class MyModel(models.Model): title = LocalizedField() description = LocalizedBleachField()
LocalizedCharField
andLocalizedTextField
Instead of
LocalizedField
save empty strings as '', this is a Django convention.LocalizedCharField
usesform.TextInput
widget.Example usage:
from localized_fields.fields import (LocalizedCharField, LocalizedTextField) class MyModel(models.Model): title = LocalizedCharField() content = LocalizedTextField()
To enable widgets in the admin, you need to inherit from
LocalizedFieldsAdminMixin
:
from django.contrib import admin
from myapp.models import MyLocalizedModel
from localized_fields.admin import LocalizedFieldsAdminMixin
class MyLocalizedModelAdmin(LocalizedFieldsAdminMixin, admin.ModelAdmin):
"""Any admin options you need go here"""
admin.site.register(MyLocalizedModel, MyLocalizedModelAdmin)