Django Model Translation

Berkay Şen
6 min readJun 23, 2022

Bu dersimizde de django’daki modellerimizi multilanguage desteği sağlamayı öğreneceğiz. Veritabanımızdaki verilerimizi translate etme işlemlerini öğreneceğiz. Çok fazla konuşmadan hemen başlayalım.

İlk başta sıfır bir django projesi oluşturmuş olduğumuzu varsayalım. Sanal ortamımıza da girdikten sonra gerekli pip paketini sanal ortamımıza kurulumunu yapalım.

pip install django-modeltranslation

Şimdi ise settings.py dosyamız üzerinden bazı ayarlar yapmamız gerekiyor. Hemen bunları yapalım.

LANGUAGE_CODE = 'tr'

USE_TZ = True

USE_L10N = True

USE_I18N = True

TIME_ZONE = 'UTC'

Bu ayarların bu şekilde settings.py dosyamızda olduğundan emin olalım. Eksik ve farklı olması takdirde sorunlar ile karşılaşabiliriz. LANGUAGE_CODE ile projemizin default yani varsayılan dilini de ayarlamayı unutmayınız :)

Şimdi gelelim web sitemizde destek vereceğimiz diğer dilleri ayarlamaya..

LANGUAGES = (
('en', 'English'),
('tr', 'Turkish'),
)

Burada web sitem üzerinde hem Türkçe hem de İngilizce dil desteği sağlayacağımı söylüyorum.

Şimdi de yeni bir MIDDLEWARE ekleyelim.

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # YENİ
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Eklemiş olduğumuz yeni middleware’imiz budur:

'django.middleware.locale.LocaleMiddleware'

Şimdi ise sırada yeni bir ayar var settings.py dosyamız üzerinden yapacak olduğumuz.

LOCALE_PATHS = [
BASE_DIR / 'locale/',
]

Ana projemize locale/ adında bir boş klasör oluşturuyoruz ve ardından bu klasörün içerisine de çevrilmesini istediğimiz dillerin klasörlerini oluşturuyoruz. Yani şu şekilde olacak.

locale
├── en
└── tr

Şimdi de ana proje dosyamızdaki urls.py dosyasında güncellemeler yapalım

from django.contrib import admin
from django.urls import path
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
path('admin/', admin.site.urls),
]

urlpatterns = [
*i18n_patterns(*urlpatterns, prefix_default_language=False),
]

Burada yeni bir urlpattern tanımladık multilanguage desteği sağlayacağımız için.

Şimdi gelelim Model Translation İşlemlerimize

İlk önce settings.py dosyamıza gelip INSTALLED_APPS’e kurmuş olduğumuz pip paketini ekliyoruz.

ÖNEMLİ NOKTA

Eğer modeltranslation paketini ‘django.contrib.admin’ den sonra koyarsanız hatalarla karşılaşabilirsiniz. Bu yüzden django.contrib.admin ,yüklemiş olduğumuz paketten sonra gelmelidir.

INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'modeltranslation',
'django.contrib.admin',
]

Şimdi ise Model Translation’ın default yani varsayılan dilini ayarlayalım

MODELTRANSLATION_DEFAULT_LANGUAGE = 'tr'

Bu ayarı yaparak varsayılan model dil ayarımızı tamamladık.

Şimdi de modelimiz hangi dillere destek verecek bunu ayarlayalım. Yani sizin siteniz 5 farklı dilde destek veriyordur belki ancak model translation işlemlerinde sadece 2 farklı dillere destek vermesini istiyorsanız farklı ayarlar yapmanız gerekecektir.

MODELTRANSLATION_LANGUAGES = ('tr', 'en')

Bunları da yaptıysak bir tane basit bir product appi oluşturup çok basit bir product modeli oluşturacağım deneme işlemleri için.

from django.db import modelsclass Product(models.Model):
title = models.CharField(verbose_name="Title",max_length=50)
description = models.TextField(verbose_name="Description",max_length=5000)
price = models.PositiveIntegerField()
stock = models.PositiveSmallIntegerField()
image = models.ImageField()

Gördüğünüz gibi aşırı basit bir model oluşturdum. Bunu da en basitinden admin paneline register ettiriyorum. admin.site.register(Product) diyerek. Buraları zaten biliyorsunuz.

Şimdi model translation işlemleri için her bir app’imiz içerisinde translation.py adında dosyalar oluşturmamız gerekiyor. Örnek olarak products adında bir app oluşturdum ve bu app klasörümün içerisinde translation.py adında bir dosya daha oluşturuyorum.

Bu translation.py dosyamızın içerisine giriş yapalım.

from .models import Product
from modeltranslation.translator import TranslationOptions,register

@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('title', 'description')

İçerisine aynı admin paneline kayıt ettirir gibi bazı sınıf/lar yazacağız.

ProductTranslationOptions adında bir sınıf oluşturuyorum ve bu sınıfı da yüklemiş olduğumuz pip paketinin içerisinde olan TranslationOptions’tan miras aldırıyorum.

Ve ÇEVRİLMESİNİ İSTEDİĞİM alanları fields diyerek buraya yazıyorum. Örnek olarak görsel yüklediğimiz field’ı yani alanı çevrilmesini tabii ki de istemeyeceğimiz için bu fields listesine YAZMIYORUZ. Sadece translate işlemlerin gerçekleşmesini istediğimiz alanların isimlerini yazıyoruz.

Ardından makemigrations ve migrate işlemlerini yapalım.

Gördüğünüz gibi Modelimize daha farklı Field alanları geldi. Tr için de En için de yeni sütunlar eklendi.

Ancak ADMİN panelimize girdiğimizde bu değişiklikleri göremeyeceğiz.Bunun için modelimizi farklı şekilde admin panelimize tanıtmamız gerekiyor. Hemen admin.py dosyamıza gelelim.

from django.contrib import admin
from .models import Product

admin.site.register(Product)

Biz burada en basitinden bu şekilde kayıt ettirmiştik. Şimdi ise bu şekilde kayıt ettireceğiz.

from django.contrib import admin
from .models import Product
from modeltranslation.admin import TranslationAdmin

@admin.register(Product)
class ProductAdmin(TranslationAdmin):
list_display = ("title",)

Yaptığımız tek şey paketimizle gelen TranslationAdmin sınıfımız ile kayıt ettiriyoruz. List Display özelliği zaten model.ModelAdmin’den geldiğini biliyoruz. Admin panelimize şimdi baktığımızda ise:

Gördüğünüz gibi çevrilecek alanlarımızın [tr] ve [en] olarak yeni field alanları gelmiş bulunmakta.

Daha güzel bir görünüm istiyorsak admin sınıfımıza şunları eklememiz gerekiyor.

from django.contrib import admin
from .models import Product
from modeltranslation.admin import TranslationAdmin

@admin.register(Product)
class ProductAdmin(TranslationAdmin):
list_display = ("title",)
class Media:
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}

Class Media sınıfını da ekledikten sonra tekrar kontrol edelim.

Artık daha güzel bir görünüme sahibiz. Daha kullanışlı. Ancak bunu da mı beğenmediniz, bizde çare tükenmez. Bunun için de gelin yeni bir ayar ekleyelim admin sınıfımıza ve group_fieldsets = True diyelim.

@admin.register(Product)
class ProductAdmin(TranslationAdmin):

group_fieldsets = True

list_display = ("title",)
class Media:
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
'modeltranslation/js/tabbed_translation_fields.js',
)
css = {
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
}

Şimdi kontrol edelim admin panelimizi.

Gördüğünüz gibi artık translate edilecek alanlarımızı da gruplayarak işlemlerimizi halledebiliyoruz. Buradan sonrasını zaten sadece denemek kalıyor. İstediğiniz gibi deneyebilirsiniz,videomuz üzerinden de denemeleri inceleyebilirsiniz.

Ek olarak sitemizin dilini ayarlayabilmek için bu view’i kullanabilirsiniz. Video’da nasıl kullanabileceğinizi anlattım.

from urllib.parse import urlparse
from django.conf import settings
from django.http import HttpResponseRedirect
from django.urls.base import resolve, reverse
from django.urls.exceptions import Resolver404
from django.utils import translation


def set_language(request, language):
for lang, _ in settings.LANGUAGES:
translation.activate(lang)
try:
view = resolve(urlparse(request.META.get("HTTP_REFERER")).path)
except Resolver404:
view = None
if view:
break
if view:
translation.activate(language)
next_url = reverse(view.url_name, args=view.args, kwargs=view.kwargs)
response = HttpResponseRedirect(next_url)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language)
else:
response = HttpResponseRedirect("/")
return response

Ana projemizin klasöründeki urls.py dosyamıza da bu path’i oluşturalım.

urlpatterns = [
*i18n_patterns(*urlpatterns, prefix_default_language=False),

# YENİ
path("set_language/<str:language>", set_language, name="set-language"),
]

Bu view’i template’iniz üzerinden bu şekilde kullanabilirsiniz.Tabii ki de dil değiştirme template’ini özelleştirebilirsiniz kendi css sınıflarınızı belirterek.

<a href="{% url 'set-language' 'tr' %}">TR</a>
<a href="{% url 'set-language' 'en' %}">EN</a>

Bu dil değiştirme view’imizin kullanımını zaten video üzerinden de görebilirsiniz.

--

--