1.介绍
1.1. User
对象
(1)创建超级管理员:
python manage.py createsuperuser
(2)创建用户:
from django.contrib.auth.models import User
user = User.objects.create_user('zzj', 'zzj@qq.com', '135246')
(3)更改密码
通过命令:
python manage.py changepassword *username*
通过函数:
from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new password')
u.save()
1.2.权限
User 对象有两个多对多字段:groups 和 user_permissions
myuser.groups.set([group_list]) myuser.groups.add(group, group, ...) myuser.groups.remove(group, group, ...) myuser.groups.clear() myuser.user_permissions.set([permission_list]) myuser.user_permissions.add(permission, permission, ...) myuser.user_permissions.remove(permission, permission, ...) myuser.user_permissions.clear()
(1)默认权限
当 INSTALLED_APPS 设置了 django.contrib.auth ,执行python manage.py migrate时生成6个表:
并且,每个 Django 模型在执行python manage.py migrate时,会有四个默认权限:添加、修改、删除和查看。
(2)创建权限
例如,为 BlogPost 模型创建 can_publish 权限:
from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)
(3)分配权限
通过user_permissions将权限分配给 User,或通过 permissions 属性分配给 Group
myuser.user_permissions.set([permission_list]) myuser.user_permissions.add(permission, permission, ...) myuser.user_permissions.remove(permission, permission, ...) myuser.user_permissions.clear()
(4)权限缓存
在第一次需要获取用户对象的权限检查时, ModelBackend 会缓存它们的权限。添加权限后,需重新获取
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from myapp.models import BlogPost
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm('myapp.change_blogpost')
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.get(
codename='change_blogpost',
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm('myapp.change_blogpost') # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm('myapp.change_blogpost') # True
1.3.认证
Django 使用 sessions 和中间件将身份验证系统挂接到请求对象中。
(1)验证用户
使用 authenticate() 来验证用户。它使用 username 和 password 作为参数来验证,对每个身份验证后端( authentication backend ` )进行检查。
如果后端验证有效,则返回一个:class:`~django.contrib.auth.models.User 对象。如果后端引发 PermissionDenied 错误,将返回 None。
from django.contrib.auth import authenticate
user = authenticate(request, username=username, password=password)
(2)添加session
使用login(),在 session 中保存用户的ID
(3)登出
如果已经通过 django.contrib.auth.login() 登录的用户想退出登录,可以在视图中使用 django.contrib.auth.logout() 。需要传入 HttpRequest 对象,并且该函数不会返回值。
def logout_view(request):
from django.contrib.auth import logout
logout(request)
return redirect("/test_auth/login/")
并且会自动清除session
(4)限制对未登录用户的访问
原始方法就是检查request.user.is_authenticated,并重定向到登录页面,或者错误页。
快捷方式可通过login_required 装饰器,login_required(redirect_field_name='next', login_url=None)
未登录时访问,会重定向到 login_url,并传递路径到redirect_field_name的值中,redirect_field_name默认为next,可自定义;如果没有指定login_url,也可在settings.LOGIN_URL关联登录视图。
基于类的视图,可使用LoginRequiredMixin,且需放在继承列表的最前面。
from django.contrib.auth.mixins import LoginRequiredMixin
class MyView(LoginRequiredMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'
(5)限制权限的访问
permission_required() 装饰器
from django.contrib.auth.decorators import permission_required
@permission_required('polls.add_choice', login_url='/loginpage/')
def my_view(request):
...
和 login_required() 装饰器一样, login_url 默认是:setting:settings.LOGIN_URL 。
如果有 raise_exception 参数,那么装饰器将引发 PermissionDenied 错误,提示 the 403 (HTTP Forbidden) view 而不是跳转到登录页面。
如果想使用 raise_exception 但也想给用户登录的机会,那需要添加 login_required() 装饰器:
from django.contrib.auth.decorators import login_required, permission_required
@login_required
@permission_required('polls.add_choice', raise_exception=True)
def my_view(request):
...
基于类的视图,可使用PermissionRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin
class MyView(PermissionRequiredMixin, View):
permission_required = 'polls.add_choice'
# Or multiple of permissions:
permission_required = ('polls.view_choice', 'polls.change_choice')
(6)限制其他条件的访问
例如用户是否有特定域名的邮箱,调用 user_passes_test 装饰器,当调用返回 False 时会执行重定向:user_passes_test(test_func, login_url=None, redirect_field_name='next')
from django.contrib.auth.decorators import user_passes_test
def email_check(user):
return user.email.endswith('@example.com')
@user_passes_test(email_check)
def my_view(request):
...
基于类的视图,可UserPassesTestMixin
from django.contrib.auth.mixins import UserPassesTestMixin
class MyView(UserPassesTestMixin, View):
def test_func(self):
return self.request.user.email.endswith('@example.com')
(7)密码更改时,会话失效
修改了密码,如果不调用update_session_auth_hash(request, user),则会自动退出登录。
调用后,则会自动更新 session表,不会自动注销。