Readonly models in Django admin interface?

前端 未结 14 1543
北恋
北恋 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:14

    I have written a generic class to handle ReadOnly view depending on User permissions, including inlines ;)

    In models.py:

    class User(AbstractUser):
        ...
        def is_readonly(self):
            if self.is_superuser:
                return False
            # make readonly all users not in "admins" group
            adminGroup = Group.objects.filter(name="admins")
            if adminGroup in self.groups.all():
                return False
            return True
    

    In admin.py:

    # read-only user filter class for ModelAdmin
    class ReadOnlyAdmin(admin.ModelAdmin):
        def __init__(self, *args, **kwargs):
            # keep initial readonly_fields defined in subclass
            self._init_readonly_fields = self.readonly_fields
            # keep also inline readonly_fields
            for inline in self.inlines:
                inline._init_readonly_fields = inline.readonly_fields
            super().__init__(*args,**kwargs)
        # customize change_view to disable edition to readonly_users
        def change_view( self, request, object_id, form_url='', extra_context=None ):
            context = extra_context or {}
            # find whether it is readonly or not 
            if request.user.is_readonly():
                # put all fields in readonly_field list
                self.readonly_fields = [ field.name for field in self.model._meta.get_fields() if not field.auto_created ]
                # readonly mode fer all inlines
                for inline in self.inlines:
                    inline.readonly_fields = [field.name for field in inline.model._meta.get_fields() if not field.auto_created]
                # remove edition buttons
                self.save_on_top = False
                context['show_save'] = False
                context['show_save_and_continue'] = False
            else:
                # if not readonly user, reset initial readonly_fields
                self.readonly_fields = self._init_readonly_fields
                # same for inlines
                for inline in self.inlines:
                    inline.readonly_fields = self._init_readonly_fields
            return super().change_view(
                        request, object_id, form_url, context )
        def save_model(self, request, obj, form, change):
            # disable saving model for readonly users
            # just in case we have a malicious user...
            if request.user.is_readonly():
                # si és usuari readonly no guardem canvis
                return False
            # if not readonly user, save model
            return super().save_model( request, obj, form, change )
    

    Then, we can just inherit normally our classes in admin.py:

    class ContactAdmin(ReadOnlyAdmin):
        list_display = ("name","email","whatever")
        readonly_fields = ("updated","created")
        inlines = ( PhoneInline, ... )
    

提交回复
热议问题