Django - How to Create ModelAdmin Classes in Available Permissions

I made a simple Django application. I have one visitor model. My goal is to have two two tables displayed in the Django admin. One with all visitors and one with only those who are today.

Everything works for me with the code below, following these instructions . However, my problem is that I cannot get VisitorExpectedTodayProxy to appear in "available permissions" when editing groups on the admin page. Does anyone know how to do this?

Models.py

class Visitor(models.Model): visit_datetime = models.DateTimeField(null=True) visitor_name = models.CharField(max_length=500) #Make dummy models for different object views in admin interface class VisitorExpectedTodayProxy(Visitor): class Meta: proxy=True verbose_name = "Visitor" verbose_name_plural = "Today Visitors and Regular Visitors" 

Update:

I ran syncdb, but I still can not see it on the admin site. Syncdb results:

 $ python manage.py syncdb Syncing... No fixtures found. Synced: > django.contrib.auth > django.contrib.contenttypes > django.contrib.sessions > django.contrib.sites > django.contrib.messages > django.contrib.admin > south 
0
python django django-models django-admin
source share
5 answers
-one
source share

Here's the script. I manually entered ContentType entries for proxy objects and then created new permissions for them.

It just generates sql, which should then be run in mysql. After that, they should appear in the list of permissions for the user, where they will need to be added. Some of the naming conventions are not obvious to them.

 your_models=['proxy model', ] for model in models: model_nospace = model.replace(' ','') sql = 'insert into django_content_type (name, app_label, model) values ("%s","<<app_name>>","%s");'%(model,model_nospace) print sql for kind, permname in [('Can add','add_%s'%model_nospace), ('Can change','change_%s'%model_nospace), ('Can delete','delete_%s'%model_nospace),]: sql = 'insert into auth_permission (name, content_type_id, codename) values ("%s %s",(select id from django_content_type where name="%s"),"%s");'% (kind,model,model,permname) print sql 
+1
source share

I understand that this question was closed some time ago, but I share what worked for me if it can help others.

It turns out that even if the permissions for the proxy models I created were listed in the parent applications after syncdb , and even if I gave my non-super users all the permissions, he was still denied access to my proxy models through the administrator.

Although I have not tried the SQL-based fixes above, the Django-level bug fix worked for me. You should bypass the well-known Django error ( https://code.djangoproject.com/ticket/11154 ) and connect to the post_syncdb signal to correctly create permissions for proxy models. The code below has been changed from https://djangosnippets.org/snippets/2677/ to some comments on this thread.

I put this in myapp / models.py where my proxy models are stored. Theoretically, this can live in any of your INSTALLED_APPS after django.contrib.contenttypes , because it needs to be loaded after registering the update_contenttypes handler for the post_syncdb signal post_syncdb that we can disable it.

 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 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) 
+1
source share
  ./manage.py syncdb 

That's about it. It adds entries to the auth_permission table.

0
source share

What I did to fix this, I deleted every table (deleting only auth tables was not enough). Then I commented on the south of the installed applications in settings.py (not sure if this was causing problems).

Then I ran manage.py syncdb and now everything works.

I just need to reload all my data. I'm still not sure how this got messed up in the first place.

0
source share

All Articles