不使用Django翻译功能实现多语言项目的可行性及方案咨询
Hey there! Let's break down your questions one by one—this is totally doable, but there are clear tradeoffs to weigh depending on your project's needs.
Is a custom translation approach feasible and practical?
Absolutely feasible, but practicality depends on your use case. If you only have a small amount of static text to translate, or need hyper-specific control over how translations are stored/retrieved, a custom setup works fine. However, for most projects, you'll end up reinventing wheels that Django's built-in system already solves (like pluralization, language negotiation, or caching translations). It's great for niche scenarios, but not the first choice for standard multilingual apps.
Where to store custom translation files?
You have a few clean options:
- Project-level translations folder: Create a
translationsdirectory in your project root (next tomanage.py), with language-specific files likeen.json,es.json. This keeps all translations in one place for small-to-medium projects. - App-specific translations: For larger, modular projects, add a
translationssubfolder inside each app that needs translations. This keeps translations tied to the app's content. - Format choice: JSON is the most straightforward (easy to read/write, no extra dependencies), but YAML or even CSV works too. Just make sure to add these files to your version control (git) and use Django's
BASE_DIRsetting to reference the path reliably.
How to switch languages in templates?
First, you need to track the user's selected language (usually in a session or cookie). Here's a step-by-step approach:
- Add a language switcher form:
<form action="{% url 'set_custom_language' %}" method="post"> {% csrf_token %} <input name="next" type="hidden" value="{{ request.path }}"> <select name="lang"> <option value="en" {% if request.session.lang == 'en' %}selected{% endif %}>English</option> <option value="es" {% if request.session.lang == 'es' %}selected{% endif %}>Spanish</option> </select> <button type="submit">Switch Language</button> </form> - Create a view to handle language selection:
from django.shortcuts import redirect def set_custom_language(request): lang = request.POST.get('lang', 'en') request.session['lang'] = lang next_url = request.POST.get('next', '/') return redirect(next_url) - Build a custom template filter to fetch translations:
Create atemplatetagsfolder in one of your apps (don't forget the__init__.pyfile), then addtrans_tags.py:from django import template import json from django.conf import settings import os from django.core.cache import cache register = template.Library() @register.filter def translate(key, lang): # Cache translations to avoid reading files on every request cache_key = f"translations_{lang}" translations = cache.get(cache_key) if not translations: trans_file = os.path.join(settings.BASE_DIR, 'translations', f'{lang}.json') with open(trans_file, 'r') as f: translations = json.load(f) cache.set(cache_key, translations, 86400) # Cache for 1 day return translations.get(key, key) # Fallback to the key if translation is missing - Use the filter in templates:
{% load trans_tags %} <h1>{{ 'welcome_message'|translate:request.session.lang }}</h1>
How to handle translated content in the database?
Two common patterns work well here:
1. Separate fields per language (simple, for small projects)
Add language-specific fields directly to your model. It's easy to implement and query, but scales poorly if you add more languages later.
from django.db import models class Product(models.Model): name_en = models.CharField(max_length=200) name_es = models.CharField(max_length=200) description_en = models.TextField() description_es = models.TextField() def get_name(self, lang): return getattr(self, f'name_{lang}', self.name_en)
2. Related translation model (scalable, for larger projects)
Create a separate model to store translations, linked to your main model. This lets you add new languages without modifying the main model.
from django.db import models class Product(models.Model): sku = models.CharField(max_length=50, unique=True) class ProductTranslation(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='translations') lang = models.CharField(max_length=2, choices=[('en', 'English'), ('es', 'Spanish')]) name = models.CharField(max_length=200) description = models.TextField() class Meta: unique_together = ('product', 'lang') # Ensure one translation per language per product
To fetch a translation:
# In a view or template product = Product.objects.get(sku='ABC123') translation = product.translations.get(lang=request.session.lang) print(translation.name)
Is Django's built-in translation good, and is it recommended?
Yes, it's absolutely recommended for most multilingual Django projects—here's why:
- Mature tooling: The
makemessagescommand automatically extracts translatable strings from your templates and code, andcompilemessagescompiles them into efficient binary files. No manual key management! - Full ecosystem integration: It works seamlessly with Django's views, forms, admin, and even handles language negotiation (automatically picking the user's preferred language from their browser settings).
- Pluralization support: Different languages have complex plural rules (e.g., Spanish has two plural forms, while English has one). Django's gettext-based system handles this out of the box—something you'd have to build from scratch with a custom setup.
- Community & documentation: It's well-documented, and there's a huge community to help with any issues you run into.
Only consider a custom setup if:
- You need to handle dynamic, user-generated translations (not just static UI text).
- You're integrating with an external translation service (like a third-party API).
- You have extremely specific requirements for how translations are stored or retrieved that Django's system can't accommodate.
内容的提问来源于stack exchange,提问作者Elchinas




