Django用户认证系统 组与权限解析
Django的权限系统很简单,它可以赋予users或groups中的users以权限。
Djangoadmin后台就使用了该权限系统,不过也可以用到你自己的代码中。
User对象具有两个ManyToManyField字段,groups和user_permissions
groups=models.ManyToManyField(Group,verbose_name=_('groups'), blank=True,help_text=_('Thegroupsthisuserbelongsto.Auserwill' 'getallpermissionsgrantedtoeachof' 'theirgroups.'), related_name="user_set",related_query_name="user") user_permissions=models.ManyToManyField(Permission, verbose_name=_('userpermissions'),blank=True, help_text=_('Specificpermissionsforthisuser.'), related_name="user_set",related_query_name="user")
可以像其它的djangoModel一样来访问他们:
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()
权限Permissions
权限是作为一个Model存在的,建立一个权限就是创建一个PermissionModel的实例。
@python_2_unicode_compatible classPermission(models.Model): """ Thepermissionssystemprovidesawaytoassignpermissionstospecific usersandgroupsofusers. ThepermissionsystemisusedbytheDjangoadminsite,butmayalsobe usefulinyourowncode.TheDjangoadminsiteusespermissionsasfollows: -The"add"permissionlimitstheuser'sabilitytoviewthe"add"form andaddanobject. -The"change"permissionlimitsauser'sabilitytoviewthechange list,viewthe"change"formandchangeanobject. -The"delete"permissionlimitstheabilitytodeleteanobject. Permissionsaresetgloballypertypeofobject,notperspecificobject instance.Itispossibletosay"Marymaychangenewsstories,"butit's notcurrentlypossibletosay"Marymaychangenewsstories,butonlythe onesshecreatedherself"or"Marymayonlychangenewsstoriesthathavea certainstatusorpublicationdate." Threebasicpermissions--add,changeanddelete--areautomatically createdforeachDjangomodel. """ name=models.CharField(_('name'),max_length=255) content_type=models.ForeignKey(ContentType) codename=models.CharField(_('codename'),max_length=100) objects=PermissionManager() classMeta: 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)) defnatural_key(self): return(self.codename,)+self.content_type.natural_key() natural_key.dependencies=['contenttypes.contenttype']
字段fields
name:必需。50个字符或更少,例如,'CanVote‘
content_type:必需,一个对于django_content_type数据库table的引用,table中含有每个应用中的Model的记录。
codename:必需,100个字符或更少,例如,'can_vote'。
如果要为某个Model创建权限:
fromdjango.dbimportmodels classVote(models.Model): ... classMeta: permissions=(("can_vote","CanVote"),)
如果这个Model在应用foo中,则权限表示为'foo.can_vote',检查某个用户是否具有权限myuser.has_perm('foo.can_vote')
默认权限defaultpermissions
如果已经在INSTALLED_APPS配置了django.contrib.auth,它会保证为installedapplications中的每个DjangoModel创建3个缺省权限:add,change和delete。
这些权限会在你第一次运行manage.pymigrate(1.7之前为syncdb)时创建。当时所有的models都会建立权限。在这之后创建的新models会在再次运行manage.pymigrate时创建这些默认权限。这些权限与admin管理界面中的创建,删除,修改行为是一一对应的。
假设你有一个应用foo,其中有一个模型Bar,你可以用下述方法来测试基本权限:
- add:user.has_perm('foo.add_bar')
- change:user.has_perm('foo.change_bar')
- delete:user.has_perm('foo.delete_bar')
权限模型(Permissionmodel)一般不直接使用。
组Groups
组也是作为Model存在的:
@python_2_unicode_compatible classGroup(models.Model): """ Groupsareagenericwayofcategorizinguserstoapplypermissions,or someotherlabel,tothoseusers.Ausercanbelongtoanynumberof groups. Auserinagroupautomaticallyhasallthepermissionsgrantedtothat group.Forexample,ifthegroupSiteeditorshasthepermission can_edit_home_page,anyuserinthatgroupwillhavethatpermission. Beyondpermissions,groupsareaconvenientwaytocategorizeusersto applysomelabel,orextendedfunctionality,tothem.Forexample,you couldcreateagroup'Specialusers',andyoucouldwritecodethatwould dospecialthingstothoseusers--suchasgivingthemaccesstoa members-onlyportionofyoursite,orsendingthemmembers-onlyemail messages. """ name=models.CharField(_('name'),max_length=80,unique=True) permissions=models.ManyToManyField(Permission, verbose_name=_('permissions'),blank=True) objects=GroupManager() classMeta: verbose_name=_('group') verbose_name_plural=_('groups') def__str__(self): returnself.name defnatural_key(self): return(self.name,)
字段fields:
name:必需,80个字符或更少,例如,'AwesomeUsers'。
permissions:ManyToManyFieldtoPermission
group.permissions=[permission_list] group.permissions.add(permission,permission,...) group.permissions.remove(permission,permission,...) group.permissions.clear()
Programmaticallycreatingpermissions
除了可以使用Modelmeta来创建权限,也可以直接用代码创建。
例如,为myapp应用中的BlogPost模型创建一个can_publish权限:
frommyapp.modelsimportBlogPost fromdjango.contrib.auth.modelsimportGroup,Permission fromdjango.contrib.contenttypes.modelsimportContentType content_type=ContentType.objects.get_for_model(BlogPost) permission=Permission.objects.create(codename='can_publish', name='CanPublishPosts', content_type=content_type)
权限可以被赋予一个User对象通过它的user_permissions属性或者赋予一个Group通过它的permissions属性。
权限缓存
User的权限检查时是可以被缓存的,如果一个新权限被赋予一个User,如果再立即检查是不会被检查出来的。最简单的方法是重新fetchUser对象。
fromdjango.contrib.auth.modelsimportPermission,User fromdjango.shortcutsimportget_object_or_404 defuser_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) #Permissioncacheisrepopulatedfromthedatabase user.has_perm('myapp.change_bar')#True ...
权限装饰器
permission_required(perm[,login_url=None,raise_exception=False])
检查用户是否具有某个权限,类似于@login_required()
fromdjango.contrib.auth.decoratorsimportpermission_required @permission_required('polls.can_vote',login_url='/loginpage/') defmy_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。
例如:
{%ifperms.foo%}Youhavepermissiontodosomethinginthefooapp.
{%ifperms.foo.can_vote%}Youcanvote!
{%endif%} {%ifperms.foo.can_drive%}Youcandrive!
{%endif%} {%else%}Youdon'thavepermissiontodoanythinginthefooapp.
{%endif%}
或者:
{%if'foo'inperms%} {%if'foo.can_vote'inperms%}Inlookupworks,too.
{%endif%} {%endif%}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。