Мой сайт поддерживает несколько языков. У меня есть объект (Category), который должен иметь 1 или несколько объектов перевода (CategoryTranslation), соответствующих поддерживаемым языкам (они не так просты, поэтому, пожалуйста, не советуйте использовать приложения для перевода). Кроме того, зависимые объекты имеют ссылку на пользователя, который создает и обновляет их в последний раз.
Я хочу добавить в мою панель управления категориями:
- Поля категорий.
- Встроенный объект CategoryTranslation, инициализированный существующими языками. Например, на моем сайте поддерживается русский и английский, должны быть показаны 2 (и только 2) строковых символа: первый должен иметь нередактируемый язык поля, равный 'ru', второй - 'en'.
- После сохранения категории, новое CategoryTranslation должно получить значение поля create_by, равное текущему пользователю, отредактированное CategoryTranslation должно получить значение поля edited_by, равное текущему пользователю.
Вот что я сделал на данный момент:
class CategoryTranslationFormSet(BaseInlineFormSet):
def total_form_count(self):
return len(settings.LANGUAGES)
def _construct_form(self, i, **kwargs):
form = super(CategoryTranslationFormSet, self)._construct_form(i, **kwargs)
form.initial['language_code'] = settings.LANGUAGES[i][0]
return form
def save(self, commit=True):
translations = super(CategoryTranslationFormSet, self).save(commit=False)
for translation in translations:
if not translation.id:
translation.created_by = self.user
translation.edited_by = self.user
translation.save()
class CategoryTranslationAdmin(admin.TabularInline):
model = CategoryTranslation
formset = CategoryTranslationFormSet
max_num = 0
fields = ('title', 'description', 'language_code', 'created_by', 'created', 'edited_by', 'edited')
readonly_fields = ('created_by', 'created', 'edited_by', 'edited')
class CategoryAdmin(tree_editor.TreeEditor):
fieldsets = (
(None, {'fields': ('parent', 'is_list', 'is_active')}),
(_('Audit'), {'fields': ('created_by', 'created', 'edited_by', 'edited'),
'classes': ('collapse',)
}),
)
readonly_fields = ('created_by', 'created', 'edited_by', 'edited')
list_display = ('is_list', 'is_active')
inlines = [CategoryTranslationAdmin]
def save_model(self, request, obj, form, change):
add_user_for_audit(request, obj, change)
super(CategoryAdmin, self).save_model(request, obj, form, change)
def save_formset(self, request, form, formset, change):
formset.user = request.user
super(CategoryAdmin, self).save_formset(request, form, formset, change)
Как видите, поле max_num в CategoryTranslationAdmin равно 0 для предотвращения добавления дополнительных переводов, метод total_form_count набора форм возвращает число поддерживаемых языков и форм, инициализированных с доступными языками при создании формы.
Обновление
Я также установил для текущего пользователя значение formset в методе save_formset (self, request, form, formset, change) и использую его для заполнения полей измененных объектов в методе save () класса CategoryTranslationFormSet.
Это правильно?
Так что теперь мне нужно:
- Сделать поле language_code read_only (если я просто добавлю его в кортеж readonly_fields, я не смогу инициализировать его в форме).
- Поймите, мое решение с добавлением пользователя до сохранения правильное.