我正在我的个人网站上工作,想同时处理前端和数据库翻译(即使用2-3种语言进行翻译)。尽管已经有很多第三方应用程序可用于处理数据库中的翻译,但我认为构建自己的应用程序既有趣又有趣。
我在最后一步。到目前为止,一切都很好。快速回顾一下它的工作原理(跳过几件事):
好吧,假设我们有一个“工作”模型,其中有两个必须翻译的字段:标题和描述。现在,每当我在Job中创建新条目时,就会自动发生以下情况:
我的问题如下:
我想做的是:
我的想法是“通过添加一个专用于翻译的新区域来覆盖常规的 change_form.html ,该区域将获取与某个实例相关的所有Translation条目”(仅当该实例受制于翻译)。但不确定如何做到这一点。
(请注意,我已经自动检测到所有需要翻译的模型,并且可以轻松获取它们的特定字段)
任何帮助将不胜感激:)
答案 0 :(得分:0)
对于偶然发现此主题的任何人,我都设法解决了这个问题,并发布了自己的数据库翻译应用程序。该代码是完全开源的,可以在这里找到:https://pypi.org/project/django-database-translation/
对于我的原始帖子中提到的问题,我设法应用了以下逻辑:
以下是摘录,也可以在https://github.com/Jordan-Kowal/django_database_translation
上找到class DynamicTranslationForm(forms.ModelForm):
"""
Form to use in a ModelAdmin for any model that has fields to translate.
It will allow you to display and edit the Translation instances linked to the object.
Since fields are dynamically generated, you must override the get_fieldsets method in the admin (or else they won't show)
The "TranslatedAdmin" ModelAdmin natively use this form.
"""
# ----------------------------------------
# Core Methods
# ----------------------------------------
def __init__(self, *args, **kwargs):
"""Overridden method to dynamically add a new field for each Translation linked with our object"""
super(DynamicTranslationForm, self).__init__(*args, **kwargs)
if self.instance.pk:
self.set_translation_info()
for translation in self.translations:
self.fields[translation["fieldname"]] = translation["field"]
self.initial[translation["fieldname"]] = translation["instance"].text
def save(self, commit=True):
"""Overridden method to save the updated Translation texts"""
if self.instance.pk:
for translation in self.translations:
obj = translation["instance"]
fieldname = translation["fieldname"]
value = self.cleaned_data[fieldname]
obj.text = value
obj.save()
return super(DynamicTranslationForm, self).save(commit=commit)
# ----------------------------------------
# Custom Methods
# ----------------------------------------
def set_translation_info(self):
"""
Finds all the Translation instances linked to our object, and stores their info in an attribute
The attribute is a list of dict, each dict containing the information of one translation
"""
obj = self.instance
information = []
translations = obj.get_translations()
for translation in translations:
fieldname = create_translation_fieldname(translation)
information.append({
"instance": translation,
"fieldname": fieldname,
"field": forms.CharField(required=False, widget=forms.Textarea)
})
self.translations = information
# ADMIN.PY
class TranslatedAdmin(admin.ModelAdmin):
"""
ModelAdmin to use as parent for any model that has fields to translate
It comes with the "DynamicTranslationForm" and custom methods to display its fields
"""
# ----------------------------------------
# Config
# ----------------------------------------
form = DynamicTranslationForm
# ----------------------------------------
# Detail View
# ----------------------------------------
fieldsets = []
# ----------------------------------------
# Custom Methods
# ----------------------------------------
def get_form(self, request, obj=None, **kwargs):
"""Required for get_fieldsets"""
kwargs['fields'] = flatten_fieldsets(self.fieldsets)
return super().get_form(request, obj, **kwargs)
def get_fieldsets(self, request, obj=None):
"""
Allows us to display the field dynamically created by "DynamicTranslationForm"
The fieldnames in "DynamicTranslationForm" and this function must be identical
In other words:
- "DynamicTranslationForm" creates the fields
- This function adds fields with the same name to the fieldsets
- As a result, the fields now appear on the form
"""
fieldsets = self.fieldsets.copy()
# Get current Item
url = request.build_absolute_uri("?")
if url.endswith("/change/"):
url = url[:-8]
object_id = url.split("/")[-1]
obj = self.model.objects.get(pk=object_id)
# Create a field for each translation associated with our object
fields = []
translations = obj.get_translations()
for translation in translations:
fieldname = create_translation_fieldname(translation)
fields.append(fieldname)
# Add a fieldset with our fields
fieldsets.append(['TRANSLATIONS', {'fields': fields}])
return fieldsets