Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin - model visible to superuser, not staff user

Tags:

I am aware of syncdb and makemigrations, but we are restricted to do that in production environment.

We recently had couple of tables created on production. As expected, tables were not visible on admin for any user.
Post that, we had below 2 queries executed manually on production sql (i ran migration on my local and did show create table query to fetch raw sql)

django_content_type

INSERT INTO django_content_type(name, app_label, model) 
values ('linked_urls',"urls", 'linked_urls');

auth_permission

INSERT INTO auth_permission (name, content_type_id, codename) 
values 
('Can add linked_urls Table', (SELECT id FROM django_content_type where model='linked_urls' limit 1) ,'add_linked_urls'),
('Can change linked_urls Table', (SELECT id FROM django_content_type where model='linked_urls' limit 1) ,'change_linked_urls'),
('Can delete linked_urls Table', (SELECT id FROM django_content_type where model='linked_urls' limit 1) ,'delete_linked_urls');

Now this model is visible under super-user and is able to grant access to staff users as well, but staff users cant see it.
Is there any table entry that needs to be entered in it?

Or is there any other way to do a solve this problem without syncdb, migrations?

like image 727
NoobEditor Avatar asked Aug 24 '17 09:08

NoobEditor


People also ask

How do I restrict access to parts of Django admin?

Django admin allows access to users marked as is_staff=True . To disable a user from being able to access the admin, you should set is_staff=False . This holds true even if the user is a superuser. is_superuser=True .

How do I give staff permissions in Django?

To do this, create a group in Groups in the django admin. You can add model permissions according to the models you would wish the staff or users to have access to. Once that is done, add your your users to that group. You do that by selecting the user of interest and adding them to the created groups.

How do you get all groups that a user is a member of Django?

You can get the groups of a user with request. user. groups. all() , which will return a QuerySet .


1 Answers

We recently had couple of tables created on production.

I can read what you wrote there in two ways.

First way: you created tables with SQL statements, for which there are no corresponding models in Django. If this is the case, no amount of fiddling with content types and permissions that will make Django suddenly use the tables. You need to create models for the tables. Maybe they'll be unmanaged, but they need to exist.

Second way: the corresponding models in Django do exist, you just manually created tables for them, so that's not a problem. What I'd do in this case is run the following code, explanations follow after the code:

from django.contrib.contenttypes.management import update_contenttypes
from django.apps import apps as configured_apps
from django.contrib.auth.management import create_permissions

for app in configured_apps.get_app_configs():
    update_contenttypes(app, interactive=True, verbosity=0)

for app in configured_apps.get_app_configs():
    create_permissions(app, verbosity=0)

What the code above does is essentially perform the work that Django performs after it runs migrations. When the migration occurs, Django just creates tables as needed, then when it is done, it calls update_contenttypes, which scans the table associated with the models defined in the project and adds to the django_content_type table whatever needs to be added. Then it calls create_permissions to update auth_permissions with the add/change/delete permissions that need adding. I've used the code above to force permissions to be created early during a migration. It is useful if I have a data migration, for instance, that creates groups that need to refer to the new permissions.

like image 155
Louis Avatar answered Sep 30 '22 00:09

Louis