Opened 9 years ago

Last modified 9 years ago

#26057 closed Bug

Template {% if perms.app_label.permission %} check failing, but {% if 'app_label.permission' in perms %} works — at Version 2

Reported by: McAnix Owned by: nobody
Component: Template system Version: 1.8
Severity: Normal Keywords: permissions
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by McAnix)

I'm encountering the issue above for dynamically generated permissions.

I have a Zone model (see below) in a project named "Core" that holds some content and dynamically builds row-level-like permissions for each entry using a post_save and post_delete hook to manage it. Please don't judge me on the usage, it was the simplest solution at the time and the Zone model content changes infrequently.

The issue I'm facing is when using the dynamic permissions in a template, even as admin. I've tested the following in the template:

{% if 'core.can_view_myzone' in perms %}Check passes{% endif %} <- WORKS
{% if perms.core.can_view_myzone %}Check fails{% endif %} <- DOESN'T WORK

Also in the view:

print "CAN VIEW: %s" % request.user.has_perm('core.can_view_myzone') <- WORKS

Other permissions that are created via the permissions variable in the Meta class work fine BUT not if they're in the Zone model. I have checked migrations and the db tables for django_content_type/auth_permission and everything exists there and links correctly.

Middleware as follows:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

Template Context Processors:

TEMPLATE_CONTEXT_PROCESSORS = ('django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.contrib.messages.context_processors.messages',
'djutils.context_processors.settings_loader') # This just exposes selected settings to the templates
class Zone(models.Model):
  """A holder model for zone information as well as permission slips for each zone"""
  
  class Meta:
    permissions = ()
  
  cdate = models.DateTimeField(auto_now_add=True)
  name = models.CharField(max_length=63)
  url = models.CharField(max_length=255, verbose_name="Zone URL")
  enabled = models.BooleanField()
  
  def __unicode__(self):
    return "%s (Enabled: %s)" % (self.name, self.enabled)

def create_zone_permission(sender, instance, created, raw, using, **kwargs):
  """Creates a new zone permission entry for the new zone"""
  content_type = ContentType.objects.get(app_label='core', model='zone')
  codename = 'can_view_%s' % (instance.name, )
  name='Can View %s' % (instance.name, )
  
  if not Permission.objects.using(using).filter(codename=codename, content_type=content_type).exists():
    logger.info("Creating zone specific permissions for %s" % (codename, ))
    Permission.objects.using(using).create(codename=codename, name=name, content_type=content_type)


def delete_zone_permission(sender, instance, using, **kwargs):
  """Creates a new zone permission entry for the new zone"""
  content_type = ContentType.objects.get(app_label='core', model='zone')
  codename = 'can_view_%s' % (instance.name, )
  
  if Permission.objects.using(using).filter(codename=codename, content_type=content_type).exists():
    logger.info("Deleting zone specific permissions for %s" % (codename, ))
    permission = Permission.objects.using(using).filter(codename=codename, content_type=content_type)
    
    permission.delete(using=using)
    
post_save.connect(create_zone_permission, sender=Zone)
post_delete.connect(delete_zone_permission, sender=Zone)

Change History (2)

comment:1 by McAnix, 9 years ago

Description: modified (diff)

comment:2 by McAnix, 9 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top