【问题标题】:Set initial values for non-editable fields in Django Admin Inlines在 Django Admin Inlines 中为不可编辑字段设置初始值
【发布时间】:2012-03-29 16:46:18
【问题描述】:

我的网站支持多种语言。我有一个对象 (Category),它应该有 1 个或多个翻译对象 (CategoryTranslation) 对应于支持的语言(它们不是那么简单,所以请不要建议使用翻译应用程序)。此外,依赖对象具有指向创建和最后更新它们的用户的链接。

我想在我的类别管理面板中关注:

  1. 类别字段。
  2. 由现有语言初始化的内联 CategoryTranslation 对象。例如,在我的网站支持俄语和英语中,应显示 2 个(且仅 2 个)内联,第一个应具有不可编辑的字段语言等于“ru”,第二个 - 'en'。
  3. Category 保存后,新 CategoryTranslation 应该得到 created_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)

如您所见,CategoryTranslationAdmin 的 max_num 字段为 0 以防止添加额外的翻译,表单集的 total_form_count 方法返回支持的语言和表单创建时使用可用语言初始化的表单的计数。

更新 我还在 save_formset(self, request, form, formset, change) 方法中将当前用户设置为 formset,并使用他在 CategoryTranslationFormSet 类的 save() 方法中填充更改对象的字段。

对吗?

所以现在我需要:

  1. 将 language_code 字段设为只读(如果我只是将其添加到 readonly_fields 元组,我将无法在表单中对其进行初始化)。
  2. 了解,我的解决方案是在保存正确之前添加用户。

【问题讨论】:

    标签: django django-admin inline-formset


    【解决方案1】:

    检查这个:

    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
    

    【讨论】:

      猜你喜欢
      • 2011-12-13
      • 2015-05-21
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 2018-08-21
      • 2012-11-07
      相关资源
      最近更新 更多