Readonly models in Django admin interface?

前端 未结 14 1433
北恋
北恋 2020-12-02 05:53

How can I make a model completely read-only in the admin interface? It\'s for a kind of log table, where I\'m using the admin features to search, sort, filter etc, but there

相关标签:
14条回答
  • 2020-12-02 06:06

    I ran into the same requirement when needing to make all fields readonly for certain users in django admin ended up leveraging on django module "django-admin-view-permission" without rolling my own code. If you need more fine grained control to explicitly define which fields then you would need to extend the module. You can check out the plugin in action here

    0 讨论(0)
  • 2020-12-02 06:08

    See https://djangosnippets.org/snippets/10539/

    class ReadOnlyAdminMixin(object):
        """Disables all editing capabilities."""
        change_form_template = "admin/view.html"
    
        def __init__(self, *args, **kwargs):
            super(ReadOnlyAdminMixin, self).__init__(*args, **kwargs)
            self.readonly_fields = self.model._meta.get_all_field_names()
    
        def get_actions(self, request):
            actions = super(ReadOnlyAdminMixin, self).get_actions(request)
            del_action = "delete_selected"
            if del_action in actions:
                del actions[del_action]
            return actions
    
        def has_add_permission(self, request):
            return False
    
        def has_delete_permission(self, request, obj=None):
            return False
    
        def save_model(self, request, obj, form, change):
            pass
    
        def delete_model(self, request, obj):
            pass
    
        def save_related(self, request, form, formsets, change):
            pass
    

    templates/admin/view.html

    {% extends "admin/change_form.html" %}
    {% load i18n %}
    
    {% block submit_buttons_bottom %}
      <div class="submit-row">
        <a href="../">{% blocktrans %}Back to list{% endblocktrans %}</a>
      </div>
    {% endblock %}
    

    templates/admin/view.html (for Grappelli)

    {% extends "admin/change_form.html" %}
    {% load i18n %}
    
    {% block submit_buttons_bottom %}
      <footer class="grp-module grp-submit-row grp-fixed-footer">
        <header style="display:none"><h1>{% trans "submit options"|capfirst context "heading" %}</h1></header>
        <ul>
           <li><a href="../" class="grp-button grp-default">{% blocktrans %}Back to list{% endblocktrans %}</a></li>
        </ul>
      </footer>
    {% endblock %}
    
    0 讨论(0)
  • 2020-12-02 06:08

    With Django 2.2 I do it like this:

    @admin.register(MyModel)
    class MyAdmin(admin.ModelAdmin):
        readonly_fields = ('all', 'the', 'necessary', 'fields')
        actions = None # Removes the default delete action in list view
    
        def has_add_permission(self, request):
            return False
    
        def has_change_permission(self, request, obj=None):
            return False
    
        def has_delete_permission(self, request, obj=None):
            return False
    
    0 讨论(0)
  • 2020-12-02 06:09

    The accepted answer should work, but this will also preserve the display order of the readonly fields. You also don't have to hardcode the model with this solution.

    class ReadonlyAdmin(admin.ModelAdmin):
       def __init__(self, model, admin_site):
          super(ReadonlyAdmin, self).__init__(model, admin_site)
          self.readonly_fields = [field.name for field in filter(lambda f: not f.auto_created, model._meta.fields)]
    
       def has_delete_permission(self, request, obj=None):
           return False
       def has_add_permission(self, request, obj=None):
           return False
    
    0 讨论(0)
  • 2020-12-02 06:10

    If the accepted answer doesn't work for you, try this:

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = []
        for field in self.model._meta.fields:
            readonly_fields.append(field.name)
    
        return readonly_fields
    
    0 讨论(0)
  • 2020-12-02 06:14

    Here are two classes I am using to make a model and/or it's inlines read only.

    For model admin:

    from django.contrib import admin
    
    class ReadOnlyAdmin(admin.ModelAdmin):
        readonly_fields = []
    
        def get_readonly_fields(self, request, obj=None):
            return list(self.readonly_fields) + \
                   [field.name for field in obj._meta.fields] + \
                   [field.name for field in obj._meta.many_to_many]
    
    
        def has_add_permission(self, request):
            return False
    
        def has_delete_permission(self, request, obj=None):
            return False
    
    class MyModelAdmin(ReadOnlyAdmin):
        pass
    

    For inlines:

    class ReadOnlyTabularInline(admin.TabularInline):
        extra = 0
        can_delete = False
        editable_fields = []
        readonly_fields = []
        exclude = []
    
        def get_readonly_fields(self, request, obj=None):
            return list(self.readonly_fields) + \
                   [field.name for field in self.model._meta.fields
                    if field.name not in self.editable_fields and
                       field.name not in self.exclude]
    
        def has_add_permission(self, request):
            return False
    
    
    class MyInline(ReadOnlyTabularInline):
        pass
    
    0 讨论(0)
提交回复
热议问题