Django的權限系統很簡單,它可以賦予users或groups中的users以權限。
Django admin后臺就使用了該權限系統,不過也可以用到你自己的代碼中。
User對象具有兩個ManyToManyField字段,groups和user_permissions
groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True, help_text=_('The groups this user belongs to. A user will ' 'get all permissions granted to each of ' 'their groups.'), related_name="user_set", related_query_name="user") user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True, help_text=_('Specific permissions for this user.'), related_name="user_set", related_query_name="user")可以像其它的django Model一樣來訪問他們:
myuser.groups = [group_list]myuser.groups.add(group, group, ...)myuser.groups.remove(group, group, ...)myuser.groups.clear()myuser.user_permissions = [permission_list]myuser.user_permissions.add(permission, permission, ...)myuser.user_permissions.remove(permission, permission, ...)myuser.user_permissions.clear()
權限是作為一個Model存在的,建立一個權限就是創建一個Permission Model的實例。
@python_2_unicode_compatibleclass Permission(models.Model): """ The permissions system PRovides a way to assign permissions to specific users and groups of users. The permission system is used by the Django admin site, but may also be useful in your own code. The Django admin site uses permissions as follows: - The "add" permission limits the user's ability to view the "add" form and add an object. - The "change" permission limits a user's ability to view the change list, view the "change" form and change an object. - The "delete" permission limits the ability to delete an object. Permissions are set globally per type of object, not per specific object instance. It is possible to say "Mary may change news stories," but it's not currently possible to say "Mary may change news stories, but only the ones she created herself" or "Mary may only change news stories that have a certain status or publication date." Three basic permissions -- add, change and delete -- are automatically created for each Django model. """ name = models.CharField(_('name'), max_length=255) content_type = models.ForeignKey(ContentType) codename = models.CharField(_('codename'), max_length=100) objects = PermissionManager() class Meta: verbose_name = _('permission') verbose_name_plural = _('permissions') unique_together = (('content_type', 'codename'),) ordering = ('content_type__app_label', 'content_type__model', 'codename') def __str__(self): return "%s | %s | %s" % ( six.text_type(self.content_type.app_label), six.text_type(self.content_type), six.text_type(self.name)) def natural_key(self): return (self.codename,) + self.content_type.natural_key() natural_key.dependencies = ['contenttypes.contenttype']
字段fields
name:必需。50個字符或更少,例如,’Can Vote‘
content_type:必需,一個對于django_content_type數據庫table的引用,table中含有每個應用中的Model的記錄。
codename:必需,100個字符或更少,例如,'can_vote'。
如果要為某個Model創建權限:
from django.db import modelsclass Vote(models.Model): ... class Meta: permissions = (("can_vote", "Can Vote"),)如果這個Model在應用foo中,則權限表示為'foo.can_vote',檢查某個用戶是否具有權限myuser.has_perm('foo.can_vote')
如果已經在 INSTALLED_APPS配置了django.contrib.auth,它會保證為installed applications中的每個Django Model創建3個缺省權限:add, change 和 delete。
這些權限會在你第一次運行 manage.py migrate(1.7之前為syncdb) 時創建。當時所有的models都會建立權限。在這之后創建的新models會在再次運行 manage.py migrate時創建這些默認權限。這些權限與admin管理界面中的創建,刪除,修改行為是一一對應的。
假設你有一個應用 foo ,其中有一個模型 Bar, 你可以用下述方法來測試基本權限:
add: user.has_perm('foo.add_bar')
change: user.has_perm('foo.change_bar')
delete: user.has_perm('foo.delete_bar')
權限模型( Permission model)一般不直接使用。
組也是作為Model存在的:
@python_2_unicode_compatibleclass 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. A user in a group automatically has all the permissions granted to that group. For example, if the group Site editors has the permission can_edit_home_page, any user in that group will have that permission. Beyond permissions, groups are a convenient way to categorize users to apply some label, or extended functionality, to them. For example, you could create a group 'Special users', and you could write code that would do special things to those users -- such as giving them access to a members-only portion of your site, or sending them members-only email messages. """ name = models.CharField(_('name'), max_length=80, unique=True) permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True) objects = GroupManager() class Meta: verbose_name = _('group') verbose_name_plural = _('groups') def __str__(self): return self.name def natural_key(self): return (self.name,)
字段fields:
name:必需,80個字符或更少,例如, 'Awesome Users'。
permissions:ManyToManyField to Permission
group.permissions = [permission_list]group.permissions.add(permission, permission, ...)group.permissions.remove(permission, permission, ...)group.permissions.clear()
除了可以使用Model meta來創建權限,也可以直接用代碼創建。
例如,為myapp應用中的BlogPost模型創建一個can_publish權限:
from myapp.models import BlogPostfrom django.contrib.auth.models import Group, Permissionfrom django.contrib.contenttypes.models import ContentTypecontent_type = ContentType.objects.get_for_model(BlogPost)permission = Permission.objects.create(codename='can_publish', name='Can Publish Posts', content_type=content_type)
權限可以被賦予一個User對象通過它的user_permissions屬性或者賦予一個Group通過它的permissions屬性。
User的權限檢查時是可以被緩存的,如果一個新權限被賦予一個User,如果再立即檢查是不會被檢查出來的。最簡單的方法是重新fetch User對象。
from django.contrib.auth.models import Permission, Userfrom django.shortcuts import get_object_or_404def user_gains_perms(request, user_id): user = get_object_or_404(User, pk=user_id) #權限檢查會緩存現在的權限集 user.has_perm('myapp.change_bar') permission = Permission.objects.get(codename='change_bar') user.user_permissions.add(permission) # 檢查權限緩存集 user.has_perm('myapp.change_bar') # False # 請求新實例 user = get_object_or_404(User, pk=user_id) # Permission cache is repopulated from the database user.has_perm('myapp.change_bar') # True ...permission_required(perm[, login_url=None, raise_exception=False])
檢查用戶是否具有某個權限,類似于@login_required()
from django.contrib.auth.decorators import permission_required@permission_required('polls.can_vote', login_url='/loginpage/')def my_view(request): ...user的的權限保存在模板變量 {{ perms }}中,是django.contrib.auth.context_processors.PermWrapper實例。
{{ perms.foo }}上面的單屬性是User.has_module_perms的代理。如果user擁有foo中的任一權限,則為True
{{ perms.foo.can_vote }}上面的兩級屬性查詢是User.has_perm的代理,如果用戶擁有foo.can_vote權限則為True。
例如:
{% if perms.foo %} <p>You have permission to do something in the foo app.</p> {% if perms.foo.can_vote %} <p>You can vote!</p> {% endif %} {% if perms.foo.can_drive %} <p>You can drive!</p> {% endif %}{% else %} <p>You don't have permission to do anything in the foo app.</p>{% endif %}或者:
{% if 'foo' in perms %} {% if 'foo.can_vote' in perms %} <p>In lookup works, too.</p> {% endif %}{% endif %}
新聞熱點
疑難解答