Установите начальные значения для нередактируемых полей в Django Admin Inlines - PullRequest
1 голос
/ 13 марта 2012

Мой сайт поддерживает несколько языков. У меня есть объект (Category), который должен иметь 1 или несколько объектов перевода (CategoryTranslation), соответствующих поддерживаемым языкам (они не так просты, поэтому, пожалуйста, не советуйте использовать приложения для перевода). Кроме того, зависимые объекты имеют ссылку на пользователя, который создает и обновляет их в последний раз.

Я хочу добавить в мою панель управления категориями:

  1. Поля категорий.
  2. Встроенный объект CategoryTranslation, инициализированный существующими языками. Например, на моем сайте поддерживается русский и английский, должны быть показаны 2 (и только 2) строковых символа: первый должен иметь нередактируемый язык поля, равный 'ru', второй - 'en'.
  3. После сохранения категории, новое 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.

Это правильно?

Так что теперь мне нужно:

  1. Сделать поле language_code read_only (если я просто добавлю его в кортеж readonly_fields, я не смогу инициализировать его в форме).
  2. Поймите, мое решение с добавлением пользователя до сохранения правильное.

1 Ответ

0 голосов
/ 08 мая 2013

Отметьте это:

from django.forms.widgets import HiddenInput

def _construct_form(self, i, **kwargs):
    form = super(CategoryTranslationFormSet, self)._construct_form(i, **kwargs)
    form.empty_permitted = False # Force the translation

    if 'language_code' not in form.initial.keys():
        form.initial['language_code'] = settings.LANGUAGES[i][0]

    for k in form.fields.keys():
        lang = LANG_CHOICES[zip(*settings.LANGUAGES)[0].index(form.initial['language_code'])][1]
        if k == 'language':
            form.fields[k].widget = HiddenInput()
            form.fields[k].label = u'%s %s' % (form.fields[k].label, lang)
        else:
            form.fields[k].label = u'%s (%s)' % (form.fields[k].label, lang)                

    return form
...