[Django]-Permission to view, but not to change! – Django

24πŸ‘

βœ…

Update: Since Django 2.1 this is now built-in.

In admin.py

# Main reusable Admin class for only viewing
class ViewAdmin(admin.ModelAdmin):

    """
    Custom made change_form template just for viewing purposes
    You need to copy this from /django/contrib/admin/templates/admin/change_form.html
    And then put that in your template folder that is specified in the 
    settings.TEMPLATE_DIR
    """
    change_form_template = 'view_form.html'

    # Remove the delete Admin Action for this Model
    actions = None

    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):
        #Return nothing to make sure user can't update any data
        pass

# Example usage:
class SomeAdmin(ViewAdmin):
    # put your admin stuff here
    # or use pass

In change_form.html replace this:

{{ adminform.form.non_field_errors }}

with this:

<table>
{% for field in adminform.form %}
    <tr>
      <td>{{ field.label_tag }}:</td><td>{{ field.value }}</td>
    </tr>
{% endfor %}
</table>

Then remove the submit button by deleting this row:

{% submit_row %}
πŸ‘€dan-klasson

7πŸ‘

You can use the django-admin-view-permission application:

pip install django-admin-view-permission

INSTALLED_APPS = [
    'admin_view_permission',
    'django.contrib.admin',
    ...
]

UPDATE:

Django 2.1 has a view permission out of the box.

3πŸ‘

You can’t just view things in django admin.

There is a databrowse app for that.

3πŸ‘

One workaround would be to have an additional β€œsave” permission on your model and check in the modeladmin’s save_model method if the user has this permissions, if he has not, that would mean he can do everything in this modeladmin, except saving edited data!

3πŸ‘

To provide sample to Bernhard Vallant mention above. In my admin.py file I would place

class LogBookAdmin(admin.ModelAdmin):
    list_display        = ['dateEntry','due_date', 'controlNo', 'carrier', 'status']    
    exclude             = ['encoder_status', 'engr_status', 'chief_status', 'ischecked']

    def save_model(self, request, obj, form, change):     
        if request.user.groups.filter(name='Encoder').exists():
            pass
        else:
            return super(LogBookAdmin, self).save_model(request, obj, form, change)

Assuming I have a group name Encoder where I would like them to view Logbook only. But other group name can save any changes.

πŸ‘€Charlesliam

3πŸ‘

In django 2.1, you just need to override has_change_permission and has_delete_permission :

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    # to disable view and add you can do this 
    def has_view_permission(self, request, obj=None):
        return False

    def has_add_permission(self, request):
        return False

πŸ‘€Charlesthk

2πŸ‘

You can do this by following way:

1)You can make the fields read only if the object has been created.But doing this noone will be able to change the fields

2)You can use databrowse

3)You can use form validation ,if user is not in the selected list throw validation error if any field is changed

4)you can create a view ,if user is in your list then redirect it to normal flow or else redirect him to simple html readonly page

5)Use jquery to make the fields readonly is user is not in the list and override the save method to check any smartness.In your save method you throw error any form has changed and user is not in your list.username=request.user.username

πŸ‘€ha22109

0πŸ‘

You may also override ModelAdmin.change_view (as stated in the Django docs). Just make sure you also override save_model to make sure the user can’t update the data

πŸ‘€Asdf

0πŸ‘

Duplicate: https://stackoverflow.com/a/33543817/101831

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 actions["delete_selected"]
        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πŸ‘

I have a workaround that needs to sacrifice the change only permission. In the admin template change_form.html I check for both add and change permissions in the template and display the submit_row only if the user has both permissions. Therefore, users with change permission only are able to view change_list and change_form, but never see the buttons to submit the changes they have made.

The changes I made:

  • Create a directory in my apps templates directory like myapp/templates/admin/myapp/
  • Pull in change_form.html in the directory
  • Replace

    {% block submit_buttons_bottom %}{% submit_row %}{% endblock %}

with

{# Use change permission only as read only #}
{% if has_change_permission and has_add_permission %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% endif %}

This is far from being clean and still allows the user to change data if other ways besides the standard admin form are offered, yet maybe its enough, if you just want to protect staff from accidentally changing data they should not.

πŸ‘€Jarno

0πŸ‘

I can see with the proposed answers here, you’ll face probably more problems than you need to make for yourself, as I tried all the aforementioned answers above myself. I finally figured away around this:

The way I did it, which you’ll find in the Django Admin Cookbook, is to make the fields you want editable when creating/adding, but read only after. In other words, once you create the object, whatever fields you override in that method the link provides, will be read only and you won’t be able to edit them once added to the database model.

πŸ‘€Devin B.

0πŸ‘

This is quite of an old thread, and most people already know this, but… Django 2.0 has build-in view_permissions link to awesome view permissions

πŸ‘€dsax7

Leave a comment