1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

per-object-permissions: Made some code-formatting changes

git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@4100 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-11-25 05:18:33 +00:00
parent 1b54fc3aba
commit 6fab0ffcad
7 changed files with 141 additions and 205 deletions

View File

@ -1,31 +1,28 @@
var row_level_permission = {
copyToNew: function (id)
{
copyToNew: function (id) {
var newForm = document.getElementById("addRLPForm");
var form = document.getElementById("editRLPForm-"+id);
newForm.owner.selectedIndex = form.owner.selectedIndex;
newForm.perm.selectedIndex = form.perm.selectedIndex;
newForm.negative.checked = form.negative.checked;
},
apply_selected: function ()
{
apply_selected: function () {
var eleList = document.getElementsByName("apply_checkbox");
var formList = [];
for(var i=0; eleList.length; i++)
for (var i=0; eleList.length; i++)
{
var ele = eleList[i];
if(ele.tagName == "INPUT") {
if(ele.checked) {
if (ele.tagName == "INPUT") {
if (ele.checked) {
ele.form.submit();
}
}
}
return false;
},
init: function() {
}
}

View File

@ -10,39 +10,37 @@ class ChangeRLPManipulator(forms.Manipulator):
if ct:
self.ct = ct
perm_list = [(o.id, o.name) for o in self.ct.permission_set.order_by("name")]
obj_list = [(User, User.objects.order_by("username"))]
obj_list.extend([(Group, Group.objects.order_by("name"))])
self.fields = (
MultipleObjSelectField(field_name="owner", obj_list=obj_list),
forms.SelectField(field_name="perm", choices=perm_list),
forms.SelectField(field_name="perm", choices=perm_list),
forms.CheckboxField(field_name="negative"),
)
)
def save(self, new_data):
rlp = RowLevelPermission.objects.get(pk=new_data['id'])
self.original_object = rlp
self.manager = rlp._default_manager
self.opts = rlp._meta
owner = MultipleObjSelectField.returnObject(new_data['owner'])
owner_ct = ContentType.objects.get_for_model(owner)
owner = MultipleObjSelectField.returnObject(new_data['owner'])
owner_ct = ContentType.objects.get_for_model(owner)
model_ct = rlp.model_ct
model = model_ct.get_object_for_this_type (pk=rlp.model_id)
model_id = rlp.model_id
perm = Permission.objects.get(pk=new_data['perm'])
field_name_list = ('owner_ct', 'owner_id', 'model_ct', 'model_id', 'permission')
field_data = owner_ct.id
all_data = {'owner_id':owner.id, 'model_ct_id':model_ct.id, 'model_id':model_id, 'permission_id':perm.id}
all_data = {'owner_id': owner.id, 'model_ct_id': model_ct.id, 'model_id': model_id, 'permission_id': perm.id}
manipulators.manipulator_validator_unique_together(field_name_list, self.opts, self, field_data, all_data)
rlp.owner = owner
rlp.permission = perm
rlp.negative = new_data['negative']
@ -58,12 +56,11 @@ class AddRLPManipulator(ChangeRLPManipulator):
perm_list = [(o.id, o.name) for o in self.ct.permission_set.order_by("name")]
self.fields = (
MultipleObjSelectField(field_name="owner", obj_list=obj_list, default_text=_("Select an option")),
forms.SelectMultipleField(field_name="perm", choices=perm_list, size=3),
forms.SelectMultipleField(field_name="perm", choices=perm_list, size=3),
forms.CheckboxField(field_name="negative"),
)
)
def save(self, new_data):
owner = MultipleObjSelectField.returnObject(new_data['owner'])
self.manager = RowLevelPermission._default_manager
@ -71,68 +68,66 @@ class AddRLPManipulator(ChangeRLPManipulator):
ct = ContentType.objects.get_for_model(owner)
rlp_list = []
for i in new_data.getlist('perm'):
for i in new_data.getlist('perm'):
perm = Permission.objects.get(pk=i)
#Check that the new row level perms are unique
# Check that the new row level perms are unique.
field_name_list = ('owner_ct', 'owner_id', 'model_ct', 'model_id', 'permission')
field_data = ct.id
model_id = self.obj_instance._get_pk_val()
all_data = {'owner_id':owner.id, 'model_ct_id':self.ct.id, 'model_id':model_id, 'permission_id':perm.id}
manipulators.manipulator_validator_unique_together(field_name_list, self.opts, self, field_data, all_data)
model_id = self.obj_instance._get_pk_val()
all_data = {'owner_id': owner.id, 'model_ct_id': self.ct.id, 'model_id': model_id, 'permission_id': perm.id}
manipulators.manipulator_validator_unique_together(field_name_list, self.opts, self, field_data, all_data)
rlp = RowLevelPermission.objects.create_row_level_permission(self.obj_instance, owner, perm, negative=new_data['negative'])
rlp_list.append(rlp)
return rlp_list
return rlp_list
class MultipleObjSelectField(forms.SelectField):
"""
Extends a select field to use more then one type of model in a select field.
Uses optgroup in the select field to differentiate between object types.
obj_list should be a list of lists containing the model and a list of objects.
E.g. ((User, User.objects.all()), (Group, Group.objects.all))
If you wish to define a default text to be shown as the default option, use the
If you wish to define a default text to be shown as the default option, use the
default_text parameter. An example of default text would be "Select an option"
The remaining parameters are very similiar to the normal SelectField.
To return the object selected pass the string result to MultipleObjSelectField.returnObject(string),
it returns the object instance.
To create a key for a specific object, use: MultipleObjSelectField.returnKey(object). It has an optional
parameter for the content type (ct), if you have already determined the content type and want to save on
db queries.
"""
def __init__(self, field_name, obj_list=None,
default_text=None, size=1, is_required=False, validator_list=None,
member_name=None):
def __init__(self, field_name, obj_list=None, default_text=None, size=1,
is_required=False, validator_list=None, member_name=None):
choice_list = []
self.default_text = default_text
#Loop through the object list and create the list to be displayed
# Loop through the object list and create the list to be displayed
for obj, obj_choices in obj_list:
ct = ContentType.objects.get_for_model(obj)
object_choice = [(MultipleObjSelectField.returnKey(o, ct=ct), str(o)) for o in obj_choices]
choice_list.extend([(ct.name.title(), object_choice)])
super(MultipleObjSelectField, self).__init__(field_name, choices=choice_list,
size=size, is_required=is_required,
validator_list=validator_list,
member_name=member_name)
super(MultipleObjSelectField, self).__init__(field_name, choices=choice_list,
size=size, is_required=is_required, validator_list=validator_list, member_name=member_name)
def render(self, data):
from django.utils.html import escape
output = ['<select id="%s" class="v%s%s" name="%s" size="%s">' % \
(self.get_id(), self.__class__.__name__,
self.is_required and ' required' or '', self.field_name, self.size)]
str_data = str(data) # normalize to string
if self.default_text:
selected_html = ''
if not str_data:
selected_html = ' selected="selected"'
output.append(' <option %s>%s</option>' % (selected_html, escape(self.default_text)))
output.append(' <option %s>%s</option>' % (selected_html, escape(self.default_text)))
for obj, obj_choices in self.choices:
output.append(' <optgroup label="%s">' % (obj,))
for value, display_name in obj_choices:
@ -142,8 +137,8 @@ class MultipleObjSelectField(forms.SelectField):
output.append(' <option value="%s"%s>%s</option>' % (escape(value), selected_html, escape(display_name)))
output.append(' </optgroup>')
output.append(' </select>')
return '\n'.join(output)
return '\n'.join(output)
def returnObject(data):
data = data.split('/')
ct = ContentType.objects.get(app_label__exact=data[0], model__exact=data[1])
@ -153,10 +148,7 @@ class MultipleObjSelectField(forms.SelectField):
def returnKey(obj, ct=None):
if not ct:
ct = ContentType.objects.get_for_model(obj.__class__)
return ct.app_label+"/"+ct.model+"/"+str(obj.id)
return ct.app_label + "/" + ct.model + "/" + str(obj.id)
returnObject = staticmethod(returnObject)
returnKey = staticmethod(returnKey)

View File

@ -128,14 +128,14 @@ class FormFieldCollectionWrapper(object):
class TabularBoundRelatedObject(BoundRelatedObject):
def __init__(self, related_object, field_mapping, original):
super(TabularBoundRelatedObject, self).__init__(related_object, field_mapping, original)
self.field_wrapper_list = [FieldWrapper(field) for field in self.relation.editable_fields()]
fields = self.relation.editable_fields()
self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping, fields, i)
for (i,field_mapping) in self.field_mappings.items() ]
self.original_row_needed = max([fw.use_raw_id_admin() for fw in self.field_wrapper_list])
if original:
self.original = original
@ -155,7 +155,7 @@ class StackedBoundRelatedObject(BoundRelatedObject):
if original:
self.original = original
self.show_url = original and hasattr(self.relation.opts, 'get_absolute_url')
def template_name(self):

View File

@ -100,22 +100,19 @@ if docutils_is_available:
for name, urlbase in ROLES.items():
create_reference_role(name, urlbase)
#Based off work by Ian Holsman
#http://svn.zyons.python-hosting.com/trunk/zilbo/common/utils/misc.py
# Based off work by Ian Holsman
# http://svn.zyons.python-hosting.com/trunk/zilbo/common/utils/misc.py
import sha
from django.conf import settings
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
def verify_objref_hash( content_type_id, object_id, hash ):
def verify_objref_hash(content_type_id, object_id, hash_):
hash_match = sha.new("%s/%s" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest()
if hash == hash_match:
return True
else:
return False
return hash_ == hash_match
def create_objref(object):
content_type_id = ContentType.objects.get_for_model( object ).id
content_type_id = ContentType.objects.get_for_model(object).id
object_id = object.id
return "%s/%d/%s" % ( content_type_id, object_id, sha.new("%s/%d" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest())
return "%s/%d/%s" % (content_type_id, object_id, sha.new("%s/%d" % (content_type_id, object_id) + settings.SECRET_KEY).hexdigest())

View File

@ -49,54 +49,48 @@ class Permission(models.Model):
class RowLevelPermissionManager(models.Manager):
def create_row_level_permission(self, model_instance, owner, permission, negative=False):
model_ct=ContentType.objects.get_for_model(model_instance)
model_ct = ContentType.objects.get_for_model(model_instance)
if isinstance(permission, str):
permission = Permission.objects.get(codename__exact=permission, content_type=model_ct.id)
permission = Permission.objects.get(codename=permission, content_type=model_ct.id)
if model_ct != permission.content_type:
raise TypeError, "Invalid value: Permission content type(%s) and object content type(%s) do not match" % (permission.content_type, type_ct)
raise TypeError, "Permission content type (%s) and object content type (%s) do not match" % (permission.content_type, type_ct)
model_id = model_instance._get_pk_val()
rowLvlPerm = self.model(model_id=model_id, model_ct=model_ct,
owner_id=owner.id, owner_ct=ContentType.objects.get_for_model(owner),
permission=permission, negative=negative)
rowLvlPerm.save()
return rowLvlPerm
row_lvl_perm = self.model(model_id=model_id, model_ct=model_ct, owner_id=owner.id,
owner_ct=ContentType.objects.get_for_model(owner),
permission=permission, negative=negative)
row_lvl_perm.save()
return row_lvl_perm
def create_default_row_permissions(self, model_instance, owner, change=True, delete=True, negChange=False, negDel=False):
ret_dict = {}
model_ct = ContentType.objects.get_for_model(model_instance)
if change:
change_str = "change_%s" % (model_ct.model)
ret_dict[change_str]=self.create_row_level_permission(model_instance, owner, change_str, negative=negChange)
ret_dict[change_str] = self.create_row_level_permission(model_instance, owner, change_str, negative=negChange)
if delete:
delete_str = "delete_%s" % (model_ct.model)
ret_dict[delete_str]=self.create_row_level_permission(model_instance, owner, delete_str, negative=negDel)
return ret_dict
def get_model_list(self,user, model, perm):
model_ct=ContentType.objects.get_for_model(model)
ret_dict[delete_str] = self.create_row_level_permission(model_instance, owner, delete_str, negative=negDel)
return ret_dict
def get_model_list(self, user, model, perm):
model_ct = ContentType.objects.get_for_model(model)
if isinstance(perm, str):
perm = Permission.objects.get(codename__exact=perm, content_type=model_ct.id)
user_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(User),
owner_id=user.id, permission=perm.id,
model_ct=model_ct
).values('model_id')
id_list = [o['model_id'] for o in user_model_ids]
user_group_list = [g['id'] for g in user.groups.select_related().values('id')]
user_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(User),
owner_id=user.id, permission=perm.id, model_ct=model_ct).values('model_id')
id_list = [o['model_id'] for o in user_model_ids]
user_group_list = [g['id'] for g in user.groups.select_related().values('id')]
if user_group_list:
group_model_ids = RowLevelPermission.objects.filter(owner_ct=ContentType.objects.get_for_model(Group).id,
owner_id__in=user_group_list,
model_ct = model_ct
).values('model_id')
id_list=id_list + [o['model_id'] for o in group_model_ids]
owner_id__in=user_group_list, model_ct = model_ct).values('model_id')
id_list = id_list + [o['model_id'] for o in group_model_ids]
return id_list
class RowLevelPermission(models.Model):
"""
"""
Similiar to permissions but works on instances of objects instead of types.
This uses generic relations to minimize the number of tables, and connects to the
This uses generic relations to minimize the number of tables, and connects to the
permissions table using a many to one relation.
"""
model_id = models.PositiveIntegerField("'Model' ID")
model_ct = models.ForeignKey(ContentType, verbose_name="'Model' content type", related_name="model_ct")
@ -104,27 +98,24 @@ class RowLevelPermission(models.Model):
owner_ct = models.ForeignKey(ContentType, verbose_name="'Owner' content type", related_name="owner_ct")
negative = models.BooleanField()
permission = models.ForeignKey(Permission)
model = models.GenericForeignKey(fk_field='model_id', ct_field='model_ct')
owner = models.GenericForeignKey(fk_field='owner_id', ct_field='owner_ct')
objects = RowLevelPermissionManager()
class Meta:
verbose_name = _('row level permission')
verbose_name_plural = _('row level permissions')
unique_together = (('model_ct', 'model_id', 'owner_id', 'owner_ct', 'permission'),)
unique_together = (('model_ct', 'model_id', 'owner_id', 'owner_ct', 'permission'),)
class Admin:
hidden = True
def __str__(self):
return "%s | %s:%s | %s:%s" % (self.permission, self.owner_ct, self.owner, self.model_ct, self.model)
def __repr__(self):
return "%s | %s:%s | %s:%s" % (self.permission, self.owner_ct, self.owner, self.model_ct, self.model)
class Group(models.Model):
"""Groups are a generic way of categorizing users to apply permissions, or some other label, to those users. A user can belong to any number of groups.
@ -179,7 +170,7 @@ class User(models.Model):
groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True,
help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))
user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, filter_interface=models.HORIZONTAL)
row_level_permissions_owned = models.GenericRelation(RowLevelPermission, object_id_field="owner_id", content_type_field="owner_ct", related_name="owner")
objects = UserManager()
@ -283,32 +274,23 @@ class User(models.Model):
return self._perm_cache
def check_row_level_permission(self, permission, object):
object_ct=ContentType.objects.get_for_model(object)
object_ct = ContentType.objects.get_for_model(object)
if isinstance(permission, str):
try:
permission = Permission.objects.get(codename__exact=permission, content_type=object_ct.id)
permission = Permission.objects.get(codename=permission, content_type=object_ct.id)
except Permission.DoesNotExist:
return False
try:
model_id = object._get_pk_val()
row_level_perm=self.row_level_permissions_owned.get(model_id=model_id,
model_ct=object_ct.id,
permission=permission.id)
row_level_perm = self.row_level_permissions_owned.get(model_id=model_id,
model_ct=object_ct.id, permission=permission.id)
except RowLevelPermission.DoesNotExist:
return self.check_group_row_level_permissions(permission, object)
return not row_level_perm.negative
def check_group_row_level_permissions(self, permission, object):
#SELECT rlp."negative"
#FROM "auth_user_groups" ug, "auth_rowlevelpermission" rlp
#WHERE rlp."owner_id"=ug."group_id"
#AND ug."user_id"=%s
#AND rlp."owner_ct_id"=%s
#AND rlp."model_id"=%s
#AND rlp."model_ct_id"=%s
#AND rlp."permission_id"=%s;
model_id = object._get_pk_val()
cursor = connection.cursor()
cursor = connection.cursor()
sql = """
SELECT rlp.%s
FROM %s ug, %s rlp
@ -325,17 +307,15 @@ class User(models.Model):
backend.quote_name('owner_ct_id'), backend.quote_name('model_id'),
backend.quote_name('model_ct_id'), backend.quote_name('permission_id'),
backend.quote_name('negative'))
cursor.execute(sql, [self.id,
ContentType.objects.get_for_model(Group).id,
cursor.execute(sql, [self.id,
ContentType.objects.get_for_model(Group).id,
model_id,
ContentType.objects.get_for_model(object).id,
permission.id,])
row = cursor.fetchone()
if row is None:
return None
return not row[0]
def has_perm(self, perm, object=None):
"Returns True if the user has the specified permission."
@ -344,7 +324,7 @@ class User(models.Model):
if self.is_superuser:
return True
if object and object._meta.row_level_permissions:
#Since we use the content type for row level perms, we don't need the application name
# Since we use the content type for row level perms, we don't need the application name.
permission_str = perm[perm.index('.')+1:]
row_level_permission = self.check_row_level_permission(permission_str, object)
if row_level_permission is not None:
@ -360,7 +340,7 @@ class User(models.Model):
def contains_permission(self, perm, model=None):
"""
This checks if the user has the given permission for any instance
This checks if the user has the given permission for any instance
of the given model.
"""
if self.has_perm(perm):
@ -369,29 +349,20 @@ class User(models.Model):
perm = perm[perm.index('.')+1:]
return self.contains_row_level_perm(perm, model)
return False
def contains_row_level_perm(self, perm, model):
model_ct = ContentType.objects.get_for_model(model)
if isinstance(perm, str):
permission = Permission.objects.get(codename__exact=perm, content_type=model_ct.id)
else:
permission = perm
count = self.row_level_permissions_owned.filter(model_ct=model_ct.id, permission=permission.id).count()
if count>0:
count = self.row_level_permissions_owned.filter(model_ct=model_ct.id, permission=permission.id).count()
if count > 0:
return True
return self.contains_group_row_level_perms(permission, model_ct)
return self.contains_group_row_level_perms(permission, model_ct)
def contains_group_row_level_perms(self, perm, ct):
#SELECT COUNT(*)
#FROM "auth_user_groups" ug, "auth_rowlevelpermission" rlp, "django_content_type" ct
#WHERE rlp."owner_id" = ug."group_id"
#AND ug."user_id"=%s
#AND rlp."negative" = False
#AND rlp."owner_ct_id" = %s
#AND rlp."model_ct_id" = %s
cursor = connection.cursor()
cursor = connection.cursor()
sql = """
SELECT COUNT(*)
FROM %s ug, %s rlp, %s ct
@ -401,14 +372,14 @@ class User(models.Model):
AND rlp.%s = %%s
AND rlp.%s = %%s
AND rlp.%s = %%s""" % (
backend.quote_name('auth_user_groups'), backend.quote_name('auth_rowlevelpermission'),
backend.quote_name('auth_user_groups'), backend.quote_name('auth_rowlevelpermission'),
backend.quote_name('django_content_type'), backend.quote_name('owner_id'),
backend.quote_name('group_id'), backend.quote_name('user_id'),
backend.quote_name('negative'), backend.quote_name('owner_ct_id'),
backend.quote_name('model_ct_id'), backend.quote_name('permission_id'))
cursor.execute(sql, [self.id, False, ContentType.objects.get_for_model(Group).id, ct.id, perm.id])
count = int(cursor.fetchone()[0])
return (count>0)
return count > 0
def has_module_perms(self, app_label):
"Returns True if the user has any permissions in the given app label."
@ -416,19 +387,12 @@ class User(models.Model):
return False
if self.is_superuser:
return True
if bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label])):
if [p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]:
return True
return self.has_module_row_level_perms(app_label)
def has_module_row_level_perms(self, app_label):
#SELECT COUNT(*)
#FROM "django_content_type" ct, "auth_rowlevelpermission" rlp
#WHERE rlp."model_ct_id" = ct."id"
#AND ct."app_label"=%s
#AND rlp."negative" = False
#AND rlp."owner_ct_id" = %s
#AND rlp."owner_id" = %s
cursor = connection.cursor()
cursor = connection.cursor()
sql = """
SELECT COUNT(*)
FROM %s ct, %s rlp
@ -437,30 +401,20 @@ class User(models.Model):
AND rlp.%s = %%s
AND rlp.%s = %%s
AND rlp.%s = %%s
""" % (
""" % (
backend.quote_name('django_content_type'), backend.quote_name('auth_rowlevelpermission'),
backend.quote_name('model_ct_id'), backend.quote_name('id'),
backend.quote_name('app_label'),
backend.quote_name('app_label'),
backend.quote_name('owner_ct_id'),
backend.quote_name('owner_id'),backend.quote_name('negative'), )
#import pdb
#pdb.set_trace()
cursor.execute(sql, [app_label, ContentType.objects.get_for_model(User).id, self.id, False])
cursor.execute(sql, [app_label, ContentType.objects.get_for_model(User).id, self.id, False])
count = int(cursor.fetchone()[0])
if count>0:
if count > 0:
return True
return self.has_module_group_row_level_perms(app_label)
def has_module_group_row_level_perms(self, app_label):
#SELECT COUNT(*)
#FROM "auth_user_groups" ug, "auth_rowlevelpermission" rlp, "django_content_type" ct
#WHERE rlp."owner_id" = ug."group_id"
#AND ug."user_id"=%s
#AND rlp."model_ct_id" = ct."id"
#AND ct."app_label"=%s
#AND rlp."negative" = False
#AND rlp."owner_ct_id" = %s
cursor = connection.cursor()
cursor = connection.cursor()
sql = """
SELECT COUNT(*)
FROM %s ug, %s rlp, %s ct
@ -470,7 +424,7 @@ class User(models.Model):
AND ct.%s=%%s
AND rlp.%s = %%s
AND rlp.%s = %%s""" % (
backend.quote_name('auth_user_groups'), backend.quote_name('auth_rowlevelpermission'),
backend.quote_name('auth_user_groups'), backend.quote_name('auth_rowlevelpermission'),
backend.quote_name('django_content_type'), backend.quote_name('owner_id'),
backend.quote_name('group_id'), backend.quote_name('user_id'),
backend.quote_name('model_ct_id'), backend.quote_name('id'),
@ -478,8 +432,7 @@ class User(models.Model):
backend.quote_name('owner_ct_id'))
cursor.execute(sql, [self.id, app_label, False, ContentType.objects.get_for_model(Group).id])
count = int(cursor.fetchone()[0])
return (count>0)
return (count>0)
def get_and_delete_messages(self):
messages = []

View File

@ -1,26 +1,24 @@
from django import template
from django.template import loader
from django.conf import settings
from django.conf import settings
register = template.Library()
def if_has_perm(parser, token):
"""
TODO: Update document
Checks permission on the given user. Will check
row level permissions if an object is given.
Note: Perm name should be in the format of [app_label].[perm codename]
"""
Checks permission on the given user. Checks row-level permissions if an
object is given.
Perm name should be in the format [app_label].[perm codename].
"""
tokens = token.split_contents()
if len(tokens)<2:
raise template.TemplateSyntaxError, "%r tag requires at least 1 arguments" % tokens[0]
if len(tokens)>4:
if len(tokens) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least 1 argument" % tokens[0]
if len(tokens) > 4:
raise template.TemplateSyntaxError, "%r tag should have no more then 3 arguments" % tokens[0]
nodelist_true = parser.parse(('else', 'end_'+tokens[0],))
token = parser.next_token()
if token.contents == 'else':
@ -28,24 +26,24 @@ def if_has_perm(parser, token):
parser.delete_first_token()
else:
nodelist_false = template.NodeList()
object_var = None
not_flag = False
if tokens[1] is "not":
if tokens[1] == "not":
not_flag = True
permission=tokens[2]
if len(tokens)>3:
permission = tokens[2]
if len(tokens) > 3:
object_var = parser.compile_filter(tokens[3])
else:
permission=tokens[1]
if len(tokens)>2:
permission = tokens[1]
if len(tokens) > 2:
object_var = parser.compile_filter(tokens[2])
if not (permission[0] == permission[-1] and permission[0] in ('"', "'")):
if not (permission[0] == permission[-1] and permission[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tokens[0]
return HasPermNode(permission[1:-1], not_flag, object_var, nodelist_true, nodelist_false)
class HasPermNode(template.Node):
def __init__(self, permission, not_flag, object_var, nodelist_true, nodelist_false):
self.permission = permission
@ -70,7 +68,7 @@ class HasPermNode(template.Node):
nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype))
return nodes
def render(self, context):
def render(self, context):
if self.object_var:
try:
object = self.object_var.resolve(context)
@ -78,17 +76,17 @@ class HasPermNode(template.Node):
object = None
else:
object=None
try:
user = template.resolve_variable("user", context)
except template.VariableDoesNotExist:
return settings.TEMPLATE_STRING_IF_INVALID
bool_perm = user.has_perm(self.permission, object=object)
if (self.not_flag and not bool_perm) or (not self.not_flag and bool_perm):
return self.nodelist_true.render(context)
if (self.not_flag and bool_perm) or (not self.not_flag and not bool_perm):
return self.nodelist_false.render(context)
return ''
register.tag('if_has_perm', if_has_perm)
register.tag('if_has_perm', if_has_perm)

View File

@ -233,7 +233,6 @@ class AutomaticManipulator(forms.Manipulator):
new_rel_obj.delete()
self.fields_deleted.append('%s "%s"' % (related.opts.verbose_name, old_rel_obj))
# Save the order, if applicable.
if self.change and self.opts.get_ordered_objects():
order = new_data['order_'] and map(int, new_data['order_'].split(',')) or []