2013-02-23 10 views
7

Rozszerzyłem stronę administratora Django dla mojej aplikacji, aby umożliwić dostęp innym osobom nieupoważnionym/superużytkownikom. To działa dobrze.Uprawnienia modelu proxy dla Django nie pojawiają się

Stworzyłem model proxy dla istniejącego modelu i zarejestrowałem go na mojej stronie administratora, jednak nie jest on wyświetlany dla użytkowników niebędących pracownikami. Z dokumentacji, którą przeczytałem, rozumiem, że modele proxy mają własne uprawnienia. Sprawdziłem i te nie pojawiają się na liście dostępnych uprawnień.

Oto mój kod w przypadku pomaga:

Normalny model

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' 

Proxy model

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

model Admin

class NewRequestsAdmin(ModelAdmin): 
pass 

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

klienta Admin Rejestracja

myapps_admin_site.register(NewRequests, NewRequestsAdmin) 

Byłem zarządzania mój DB z Południa. Zgodnie z this post, musisz trochę go zmodyfikować, postępując zgodnie z the instructions it points users to. To była porażka. Mój DB nie zawiera w sobie wielu informacji, więc odkomentowałem Południe i uruchomiłem zwykły syncdb, aby wykluczyć Południe. Niestety, to wciąż nie działa, a ja nie mogę. Każda pomoc jest doceniana.

Edit

To było na Django 1.4

Odpowiedz

7

Okazuje się, że nie zrobił nic złego. Szukałem uprawnieniami pod

myapp | New Request | Can add new request

Uprawnienia objęte modelu nadrzędnego.

myapp | engagement | Can add new request

+0

Miałem również ten problem. –

+0

jakiej wersji django używasz? Mam tę samą konfigurację w wersji 1.4 i nie jest ona rozwiązana, więc zastanawiam się, kiedy została ona rozwiązana? – fastmultiplication

+0

To również używało wersji 1.4. Nie wiem, dlaczego nie zostało to rozwiązane. Zaktualizowałem oryginalny post z wersją. – chirinosky

1

Rozumiem to pytanie zostało zamknięte jakiś czas temu, ale dzielę co pracował dla mnie w przypadku może pomóc innym.

Okazuje się, że nawet jeśli uprawnienia do tworzonych przeze mnie modeli proxy zostały wymienione w aplikacjach nadrzędnych (jako @chirinosky), o których wspomniałem, i mimo, że przyznano mi nie-superużytkownikowi wszystkie uprawnienia, to nadal odmawiano mi dostępu do moich modele proxy za pośrednictwem administratora.

Co musiałem zrobić, to obejść znany błąd Django (https://code.djangoproject.com/ticket/11154) i połączyć się z sygnałem post_syncdb, aby odpowiednio utworzyć uprawnienia dla modeli proxy. Poniższy kod został zmodyfikowany z https://djangosnippets.org/snippets/2677/ dla niektórych komentarzy w tym wątku.

Umieściłem to w myapp/models.py, w którym były moje modele proxy.Teoretycznie może to być dowolne z twojego INSTALLED_APPS po django.contrib.contenttypes, ponieważ musi zostać załadowane po zarejestrowaniu sterownika update_contenttypes dla sygnału post_syncdb, abyśmy mogli go odłączyć.

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

Istnieje obejście, można go zobaczyć tutaj: https://gist.github.com/magopian/7543724

To może się różnić w zależności od wersji django, ale stosowania zasady są takie same.

Testowane z 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)) 

Jak korzystać

  • utworzyć katalog /myproject/myapp/management/commands
  • utworzyć plik /myproject/myapp/management/__init__.py
  • utworzyć plik /myproject/myapp/management/commands/__init__.py
  • zapisać kod powyżej do /myproject/myapp/management/commands/fix_permissions.py
  • uruchom /manage.py fix_permissions
+0

Link do potencjalnego rozwiązania jest zawsze mile widziany, ale proszę [dodaj kontekst wokół linku] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really -good-answers/8259 # 8259), więc Twoi koledzy użytkownicy będą mieli pojęcie, co to jest i dlaczego tam jest. Zawsze podawaj najważniejszą część ważnego linku, na wypadek, gdyby strona docelowa była nieosiągalna lub stała w trybie offline. Weź pod uwagę, że jest to niewiele więcej niż link do strony zewnętrznej, która jest prawdopodobnie powodem [Dlaczego i jak niektóre odpowiedzi zostały usunięte?] (Http://stackoverflow.com/help/deleted-answers). – FelixSFD

+0

Pewnie. Poprawię moją odpowiedź. Dzięki! – vinagreti

+0

@FelixSFD Dzięki za pomoc. Teraz jest o wiele lepiej i pomocny. – vinagreti

Powiązane problemy