【问题标题】:Django admin - remove field if editing an objectDjango admin - 如果编辑对象则删除字段
【发布时间】:2010-05-19 15:23:08
【问题描述】:

我有一个可以通过 Django 管理区域访问的模型,如下所示:

# model
class Foo(models.Model):
    field_a = models.CharField(max_length=100)
    field_b = models.CharField(max_length=100)

# admin.py
class FooAdmin(admin.ModelAdmin):
    pass

假设如果用户正在添加一个对象,我想显示 field_a 和 field_b,但如果用户正在编辑一个对象,则只显示 field_a。有没有一种简单的方法可以做到这一点,也许使用 fields 属性?

如果有的话,我可以破解一个 JavaScript 解决方案,但这样做根本不合适!

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    您可以为管理员创建自定义ModelForm 以将字段放入__init__

    class FooForm(forms.ModelForm):
        class Meta(object):
            model = Foo
    
        def __init__(self, *args, **kwargs):
            super(FooForm, self).__init__(*args, **kwargs)
            if self.instance and self.instance.pk:
                # Since the pk is set this is not a new instance
                del self.fields['field_b']
    
    class FooAdmin(admin.ModelAdmin):
        form = FooForm
    

    编辑:从 John 的评论中获取关于将该字段设为只读的提示,您可以将其设为隐藏字段并覆盖 clean 以确保值不会更改。

    class FooForm(forms.ModelForm):
        class Meta(object):
            model = Foo
    
        def __init__(self, *args, **kwargs):
            super(FooForm, self).__init__(*args, **kwargs)
            if self.instance and self.instance.pk:
                # Since the pk is set this is not a new instance
                self.fields['field_b'].widget = forms.HiddenInput()
    
        def clean_field_b(self):
            if self.instance and self.instance.pk:
                return self.instance.field_b
            else:
                return self.cleaned_data['field_b']  
    

    【讨论】:

    • 感谢您的回答!看起来它应该可以工作,但是在编辑对象时出现 TemplateSyntaxError - “在表单中找不到键 'field_b'”。知道如何解决这个问题吗?
    • 我通过将字段更改为 CharField(它最初是一个选择列表)并将其标记为只读来解决这个问题 - 这对我的目的来说很好。类似于: self.fields['field_b'] = forms.CharField(initial="initial value"); self.fields['field_b'].widget.attrs['readonly'] = True
    • 废话我忘记了管理员使用 ModelAdmin 字段集而不是模型上的字段来生成模板,但我很高兴你能成功。
    • 不用担心。我也玩过将它换成隐藏字段,但它会将标签留在左边,这有点难看。 :) 再次感谢您的帮助!
    • 作为参考,如果一个人想要创建一个自定义的 ModelForm,那么像这里的第一个示例那样在 ModelAdmin 中指定表单是不够的。您必须覆盖 ModelAdmin 的 get_form() 方法,如下所述:stackoverflow.com/questions/4291516/…
    【解决方案2】:

    您还可以执行以下操作

    class FooAdmin(admin.ModelAdmin)
        def change_view(self, request, object_id, extra_context=None):       
            self.exclude = ('field_b', )
            return super(SubSectionAdmin, self).change_view(request, object_id, extra_context)
    

    取自这里Django admin: exclude field on change form only

    【讨论】:

      猜你喜欢
      • 2016-12-11
      • 2018-01-18
      • 2015-05-21
      • 1970-01-01
      • 2018-02-17
      • 2016-05-27
      • 2019-03-03
      • 1970-01-01
      • 2018-04-26
      相关资源
      最近更新 更多