2013-02-23 14 views
7

Ho esteso il sito di amministrazione Django per la mia app per consentire l'accesso non personale/superutente. Questo sta funzionando bene.Le autorizzazioni del modello proxy Django non vengono visualizzate

Ho creato un modello proxy per un modello esistente e l'ho registrato sul sito di amministrazione, tuttavia, non viene visualizzato per utenti non dipendenti. Dalla documentazione che ho letto, ho capito che i modelli proxy hanno i loro permessi. Ho controllato e questi non compaiono nell'elenco delle autorizzazioni disponibili.

Ecco il mio codice in caso aiuta:

Normale Modello

class Engagement(models.Model): 
    eng_type = models.CharField(max_length=5) 
    environment = models.CharField(max_length=8)  
    is_scoped = models.BooleanField()  

    class Meta: 
     ordering = ['eng_type', 'environment'] 
     app_label = 'myapp' 

modello Proxy

class NewRequests(Engagement): 
    class Meta: 
     proxy = True 
     app_label = 'myapp' 
     verbose_name = 'New Request' 
     verbose_name_plural = 'New Requests' 

Admin Modello

class NewRequestsAdmin(ModelAdmin): 
pass 

def queryset(self, request): 
    return self.model.objects.filter(is_scoped=0) 

personalizzato Admin Registrazione

myapps_admin_site.register(NewRequests, NewRequestsAdmin) 

Ho gestito il mio DB con il Sud. Secondo this post, è necessario manometterlo un po 'seguendo the instructions it points users to. Questo è stato un fallimento. Il mio DB non ha un sacco di informazioni in esso, quindi ho decomposto South e ho eseguito un syncdb regolare per escludere South. Purtroppo, questo non funziona ancora e sono in perdita. Qualsiasi aiuto è apprezzato.

Modifica

Questo era in Django 1.4

risposta

7

risulta non ho fatto niente di male. Cercavo le autorizzazioni in

myapp | New Request | Can add new request

Permessi di cadere sotto il modello di genitore.

myapp | engagement | Can add new request

+0

ho avuto quel problema pure. –

+0

quale versione di django stai usando? Ho lo stesso setup in 1.4 e non è risolto, quindi mi chiedo quando è stato risolto? – fastmultiplication

+0

Stava usando anche 1.4. Non sono sicuro del motivo per cui non è stato risolto per te. Ho aggiornato il post originale con la versione. – chirinosky

1

Mi rendo conto che questa domanda è stata chiusa qualche tempo fa, ma sto condividendo ciò che ha funzionato per me nel caso potrebbe aiutare gli altri.

Si è scoperto che anche se le autorizzazioni per i modelli proxy che ho creato erano elencate sotto le app principali (come @chirinosky), e nonostante avessi concesso a tutti i permessi il mio utente non super, mi è stato comunque negato l'accesso modelli proxy attraverso l'amministratore.

Quello che dovevo fare era risolvere un bug Django noto (https://code.djangoproject.com/ticket/11154) e connettersi al segnale post_syncdb per creare correttamente le autorizzazioni per i modelli proxy. Il codice riportato di seguito viene modificato da https://djangosnippets.org/snippets/2677/ per alcuni commenti su quella discussione.

L'ho inserito in myapp/models.py che conteneva i miei modelli proxy.Teoricamente, questo può vivere in uno qualsiasi dei tuoi INSTALLED_APPS dopo il django.contrib.contenttypes perché deve essere caricato dopo che il gestore update_contenttypes è registrato per il segnale post_syncdb in modo che possiamo disconnetterlo.

def create_proxy_permissions(app, created_models, verbosity, **kwargs): 
    """ 
    Creates permissions for proxy models which are not created automatically 
    by 'django.contrib.auth.management.create_permissions'. 
    See https://code.djangoproject.com/ticket/11154 
    Source: https://djangosnippets.org/snippets/2677/ 

    Since we can't rely on 'get_for_model' we must fallback to 
    'get_by_natural_key'. However, this method doesn't automatically create 
    missing 'ContentType' so we must ensure all the models' 'ContentType's are 
    created before running this method. We do so by un-registering the 
    'update_contenttypes' 'post_syncdb' signal and calling it in here just 
    before doing everything. 
    """ 
    update_contenttypes(app, created_models, verbosity, **kwargs) 
    app_models = models.get_models(app) 
    # The permissions we're looking for as (content_type, (codename, name)) 
    searched_perms = list() 
    # The codenames and ctypes that should exist. 
    ctypes = set() 
    for model in app_models: 
     opts = model._meta 
     if opts.proxy: 
      # Can't use 'get_for_model' here since it doesn't return 
      # the correct 'ContentType' for proxy models. 
      # See https://code.djangoproject.com/ticket/17648 
      app_label, model = opts.app_label, opts.object_name.lower() 
      ctype = ContentType.objects.get_by_natural_key(app_label, model) 
      ctypes.add(ctype) 
      for perm in _get_all_permissions(opts, ctype): 
       searched_perms.append((ctype, perm)) 

    # Find all the Permissions that have a content_type for a model we're 
    # looking for. We don't need to check for codenames since we already have 
    # a list of the ones we're going to create. 
    all_perms = set(Permission.objects.filter(
     content_type__in=ctypes, 
    ).values_list(
     "content_type", "codename" 
    )) 

    objs = [ 
     Permission(codename=codename, name=name, content_type=ctype) 
     for ctype, (codename, name) in searched_perms 
     if (ctype.pk, codename) not in all_perms 
    ] 
    Permission.objects.bulk_create(objs) 
    if verbosity >= 2: 
     for obj in objs: 
      sys.stdout.write("Adding permission '%s'" % obj) 


models.signals.post_syncdb.connect(create_proxy_permissions) 
# See 'create_proxy_permissions' docstring to understand why we un-register 
# this signal handler. 
models.signals.post_syncdb.disconnect(update_contenttypes) 
3

C'è una soluzione, si può vedere qui: https://gist.github.com/magopian/7543724

Può variare in base alla versione di Django, ma il priciple è lo stesso.

testato con Django 1.10.1

# -*- coding: utf-8 -*- 

"""Add permissions for proxy model. 
This is needed because of the bug https://code.djangoproject.com/ticket/11154 
in Django (as of 1.6, it's not fixed). 
When a permission is created for a proxy model, it actually creates if for it's 
base model app_label (eg: for "article" instead of "about", for the About proxy 
model). 
What we need, however, is that the permission be created for the proxy model 
itself, in order to have the proper entries displayed in the admin. 
""" 

from __future__ import unicode_literals, absolute_import, division 

import sys 

from django.contrib.auth.management import _get_all_permissions 
from django.contrib.auth.models import Permission 
from django.contrib.contenttypes.models import ContentType 
from django.core.management.base import BaseCommand 
from django.apps import apps 
from django.utils.encoding import smart_text 

class Command(BaseCommand): 
    help = "Fix permissions for proxy models." 

    def handle(self, *args, **options): 
     for model in apps.get_models(): 
      opts = model._meta 
      ctype, created = ContentType.objects.get_or_create(
       app_label=opts.app_label, 
       model=opts.object_name.lower(), 
       defaults={'name': smart_text(opts.verbose_name_raw)}) 

      for codename, name in _get_all_permissions(opts): 
       p, created = Permission.objects.get_or_create(
        codename=codename, 
        content_type=ctype, 
        defaults={'name': name}) 
       if created: 
        sys.stdout.write('Adding permission {}\n'.format(p)) 

Come utilizzare

  • creare una directory /myproject/myapp/management/commands
  • creare il file /myproject/myapp/management/__init__.py
  • creare il file /myproject/myapp/management/commands/__init__.py
  • salvare il codice sopra in /myproject/myapp/management/commands/fix_permissions.py
  • corsa /manage.py fix_permissions
+0

Un collegamento a una potenziale soluzione è sempre il benvenuto, ma per favore [aggiungi contesto intorno al link] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really -good-answers/8259 # 8259) così i tuoi utenti avranno un'idea di cosa sia e perché è lì. Citare sempre la parte più rilevante di un link importante, nel caso in cui il sito target non sia raggiungibile o sia permanentemente offline. Considera che essere appena più di un link a un sito esterno è una possibile ragione per [Perché e come vengono eliminate alcune risposte?] (Http://stackoverflow.com/help/deleted-answers). – FelixSFD

+0

Sicuro. Migliorerò la mia risposta. Grazie! – vinagreti

+0

@FelixSFD Grazie per il vostro aiuto. Ora è molto meglio e utile. – vinagreti

Problemi correlati