2017-08-24 1 views
6

Je suis au courant de syncdb et makemigrations, mais nous sommes limités à le faire dans un environnement de production.Django administrateur - modèle visible pour super-utilisateur, pas personnel utilisateur

Nous avons récemment créé deux tables en production. Comme prévu, les tables n'étaient pas visibles sur l'administrateur pour un utilisateur.
Post que, nous avons eu moins de 2 requêtes exécutées manuellement sur sql de production (j'ai couru la migration sur mon local et fait show create table requête pour aller chercher sql brut)

de 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'); 

Maintenant, thi Le modèle s est visible sous super-utilisateur et permet également d'accéder aux utilisateurs du personnel, mais les utilisateurs du personnel ne peuvent pas le voir.
Y a-t-il une entrée de table à entrer?

Ou est-il une autre façon de faire résoudre ce problème sans syncdb, migrations?

+0

Il peut y avoir un groupe pour les utilisateurs _staff_. Avez-vous accordé des autorisations à ce sujet? –

+0

oui, aussi, il y a beaucoup d'utilisateurs de personnel autonome n'appartenant à aucun groupe! – NoobEditor

+0

Ensuite, je suggère de créer le «personnel» du groupe d'utilisateurs et de l'assigner à tous les utilisateurs du personnel. Je ne suis pas dans cela, mais il devrait être possible de gérer l'assignation par une commande SQL, aussi. –

Répondre

1

Donc, finalement j'ai eu un solution.I fait beaucoup de débogage sur django et apparanetly ci-dessous fonction (à django.contrib.auth.backends) fait le travail pour fournir des autorisations.

def _get_permissions(self, user_obj, obj, from_name): 
    """ 
    Returns the permissions of `user_obj` from `from_name`. `from_name` can 
    be either "group" or "user" to return permissions from 
    `_get_group_permissions` or `_get_user_permissions` respectively. 
    """ 
    if not user_obj.is_active or user_obj.is_anonymous() or obj is not None: 
     return set() 

    perm_cache_name = '_%s_perm_cache' % from_name 
    if not hasattr(user_obj, perm_cache_name): 
     if user_obj.is_superuser: 
      perms = Permission.objects.all() 
     else: 
      perms = getattr(self, '_get_%s_permissions' % from_name)(user_obj) 
     perms = perms.values_list('content_type__app_label', 'codename').order_by() 
     setattr(user_obj, perm_cache_name, set("%s.%s" % (ct, name) for ct, name in perms)) 
    return getattr(user_obj, perm_cache_name) 

Alors quel était le problème?

question a menti dans cette requête:

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

semble bien au départ, mais la requête réelle exécutée était:

--# notice the caps case here - it looked so trivial, i didn't even bothered to look into it untill i realised what was happening internally 
INSERT INTO django_content_type(name, app_label, model) 
values ('Linked_Urls',"urls", 'Linked_Urls'); 

Alors django, en interne, lorsque vous faites migrate, assure que tout est migré dans le bas cas - et c'était le problème !!

J'ai eu une requête séparée exécutée en minuscules toutes les insertions précédentes et voila!

3

Nous avons récemment créé deux tables en production.

Je peux lire ce que vous avez écrit de deux façons.

Première façon: vous avez créé des tables avec des instructions SQL pour lesquelles il n'y a pas de modèles correspondants dans Django. Si tel est le cas, il n'est pas nécessaire de manipuler les types de contenu et les permissions qui feront que Django utilisera soudainement les tables. Vous devez créer des modèles pour les tables. Peut-être qu'ils seront unmanaged, mais ils doivent exister.

Deuxième façon: les modèles correspondants dans Django existent, vous avez juste créé des tables manuellement pour eux, donc ce n'est pas un problème. Ce que je ferais dans ce cas est exécutez le code suivant, les explications suivent après le 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) 

ce que le code ci-dessus est fait essentiellement effectuer le travail que Django exécute après il exécute les migrations. Lorsque la migration se produit, Django crée simplement des tables selon les besoins, puis une fois terminé, il appelle update_contenttypes, qui analyse la table associée aux modèles définis dans le projet et ajoute à la table django_content_type tout ce qui doit être ajouté. Ensuite, il appelle create_permissions pour mettre à jour auth_permissions avec les autorisations d'ajout/modification/suppression à ajouter. J'ai utilisé le code ci-dessus pour forcer les autorisations à être créées tôt during a migration. C'est utile si j'ai une migration de données, par exemple, qui crée des groupes qui doivent se référer aux nouvelles permissions.

+0

c'est la deuxième façon dont vous avez mentionné.Maintenant, mon problème est que je n'ai pas accès à exécuter des choses sur shell sur prod/pre-prod.Is il y a des trucs 'sql' raw que je peux transmettre aux DBA pour avoir une requête exécutée et faire le travail? – NoobEditor

+0

Vous n'avez pas ce problème. Toute commande de gestion de Django peut être exécutée en appelant 'django.core.management.call_command' à partir du code python. Si vous créez une vue qui enveloppe cette fonction, vous pouvez exécuter tout ce que vous voulez. Mais, en cas de doute, vous pouvez également appeler une commande à partir de python et, en tant que telle, une vue Django en utilisant la bibliothèque [subprocess] (https://docs.python.org/3/library/subprocess.html). Et oui, les deux façons vous permettraient d'exécuter des migrations. – Melvyn