django - did you forget to register or load this tag
Los permisos del modelo Proxy Django no aparecen (4)
Resulta que no hice nada malo. Estaba buscando los permisos bajo
myapp | New Request | Can add new request
Los permisos caen bajo el modelo principal.
myapp | engagement | Can add new request
Extendí el sitio de administración de Django para mi aplicación para permitir el acceso de no usuarios / superusuarios. Esto está funcionando bien.
Creé un modelo de proxy para un modelo existente y lo registré en mi sitio de administración, sin embargo, no aparece para usuarios que no son miembros del personal. De la documentación que leí, entiendo que los modelos proxy obtienen sus propios permisos. Revisé y estos no aparecen en la lista de permisos disponibles.
Aquí está mi código en caso de que ayude:
Modelo normal
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''
Modelo de Proxy
class NewRequests(Engagement):
class Meta:
proxy = True
app_label = ''myapp''
verbose_name = ''New Request''
verbose_name_plural = ''New Requests''
Administrador de modelo
class NewRequestsAdmin(ModelAdmin):
pass
def queryset(self, request):
return self.model.objects.filter(is_scoped=0)
Registro de administrador personalizado
myapps_admin_site.register(NewRequests, NewRequestsAdmin)
He estado administrando mi base de datos con South. Según esta publicación , debes manipularla un poco siguiendo las instrucciones a las que apunta a los usuarios . Esto fue un fracaso. Mi DB no tiene mucha información, por lo que no hice comentarios sobre South y ejecuté un syncdb regular para descartar South. Desafortunadamente, esto todavía no funciona y estoy perdido. Cualquier ayuda es apreciada.
Editar
Esto estaba en Django 1.4
Este es un error conocido en Django: https://code.djangoproject.com/ticket/11154 (ver comentarios de algunos parches)
Hay una solución, puede verla aquí: https://gist.github.com/magopian/7543724
Puede variar según tu versión de django, pero el principio es el mismo.
Probado 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))
Cómo utilizar
- crear un directorio
/myproject/myapp/management/commands
- crea el archivo
/myproject/myapp/management/__init__.py
- crea el archivo
/myproject/myapp/management/commands/__init__.py
- guarde el código anterior en
/myproject/myapp/management/commands/fix_permissions.py
- ejecutar
/manage.py fix_permissions
Me doy cuenta de que esta pregunta se cerró hace un tiempo, pero estoy compartiendo lo que funcionó para mí en caso de que pueda ayudar a otros.
Resulta que a pesar de que los permisos para los modelos de proxy que creé se enumeraron en las aplicaciones principales (como @chirinosky ) mencioné, y aunque concedí todos mis permisos a mi no superusuario, todavía se me negó el acceso a mis modelos de proxy a través de el administrador.
Lo que tenía que hacer era resolver un error conocido de Django ( https://code.djangoproject.com/ticket/11154 ) y conectarme a la señal post_syncdb
para crear correctamente los permisos para los modelos de proxy. El código a continuación se modifica desde https://djangosnippets.org/snippets/2677/ según algunos de los comentarios sobre ese hilo.
Coloqué esto en myapp / models.py que contenía mis modelos de proxy. Teóricamente, esto puede vivir en cualquiera de sus INSTALLED_APPS
después de django.contrib.contenttypes
porque debe cargarse después de que el controlador update_contenttypes
esté registrado para la señal post_syncdb
para que podamos desconectarlo.
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)