django admin在修改obj时使字段为只读,但在添加新obj时需要

frn*_*nhr 78 django django-admin

在admin中我想在修改对象时禁用一个字段,但在添加新对象时需要它.

什么是django的方式来解决这个问题?

Ber*_*ant 154

您可以覆盖管理员的get_readonly_fields方法:

class MyModelAdmin(admin.ModelAdmin):

    def get_readonly_fields(self, request, obj=None):
        if obj: # editing an existing object
            return self.readonly_fields + ('field1', 'field2')
        return self.readonly_fields
Run Code Online (Sandbox Code Playgroud)

  • 次要/主要警告:这不适用于内联.动态"添加另一个X"按钮将只读字段显示为"(无)",而不是您期望的表单字段. (16认同)

DVi*_*teR 11

如果要仅在更改视图上将所有字段设置为只读,请覆盖admin的get_readonly_fields:

def get_readonly_fields(self, request, obj=None):
    if obj: # editing an existing object
        # All model fields as read_only
        return self.readonly_fields + tuple([item.name for item in obj._meta.fields])
    return self.readonly_fields
Run Code Online (Sandbox Code Playgroud)

如果你想隐藏节省改变视图按钮:

  1. 更改视图

    def change_view(self, request, object_id, form_url='', extra_context=None):
        ''' customize edit form '''
        extra_context = extra_context or {}
        extra_context['show_save_and_continue'] = False
        extra_context['show_save'] = False
        extra_context['show_save_and_add_another'] = False # this not works if has_add_permision is True
        return super(TransferAdmin, self).change_view(request, object_id, extra_context=extra_context)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果用户尝试编辑,则更改权限:

    def has_add_permission(self, request, obj=None):
       # Not too much elegant but works to hide show_save_and_add_another button
        if '/change/' in str(request):
            return False
        return True
    
    Run Code Online (Sandbox Code Playgroud)

    此解决方案已在Django 1.11上进行了测试


Mar*_*ndi 8

基于 Bernhard Vallant 之前的出色建议的变体,它还保留了基类(如果有)提供的任何可能的自定义:

class MyModelAdmin(BaseModelAdmin):

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = super(MyModelAdmin, self).get_readonly_fields(request, obj)
        if obj: # editing an existing object
            return readonly_fields + ['field1', ..]
        return readonly_fields
Run Code Online (Sandbox Code Playgroud)


dir*_*kbo 5

Bernhard 和 Mario 的出色解决方案的更具可插拔性的解决方案,添加了对 createonly_fields 模拟到 readonly_fields 的支持:

class MyModelAdmin(admin.ModelAdmin):

    # ModelAdmin configuration as usual goes here

    createonly_fields = ['title', ]

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = list(super(MyModelAdmin, self).get_readonly_fields(request, obj))
        createonly_fields = list(getattr(self, 'createonly_fields', []))
            
        if obj:  # editing an existing object
            readonly_fields.extend(createonly_fields)
        return readonly_fields
Run Code Online (Sandbox Code Playgroud)