[Django系列]14.Django的auth认证系统

1.user用户

Django提供的认证系统是一个应用,位于settings.py的已安装应用django.contrib.auth,auth提供了后台管理机制,开发中常用,内部机制复杂,但是使用简单,而且比较重要.认证构建了一个模型,分三种,分别是:
  • user(存储用户基本信息和状态)
  • permission(权限管理)
  • group(组策略管理)
INSTALLED_APPS = [
    'django.contrib.auth', # 用户授权的一个app,admin依赖这个app,只要安装auth,会自动增加user属性
]
#article/views.py
def index(request):
    if request.user:
#       AnnomouseUser(匿名用户)
        print "当前登陆的用户是:",request.user
    else:
        print '+++++'
    return HttpResponse('test')
这个例子中,对request.user进行打印输出,只要INSTALLED_APPS安装auth,会自动增加user属性,被request对象直接使用.若是未登录的访问,会以AnnomouseUser匿名用户记录.

如果是已经登陆的用户,则会打印用户名

以下是用户登陆的逻辑
  • 必须导入模块from django.contrib.auth.models import User,Permission,Group
  • 要使用认证登陆的话,需要导入from django.contrib.auth import authenticate,login,logout
  • 登陆login需要传入参数user,登出时候不需要,因为request.session就包含了sessionid和user的关系
#coding: utf8
from django.contrib.auth.models import User,Permission,Group #需要使用三大模型必须用auth.models导
from django.contrib.auth import authenticate,login,logout #导入auth的authenticate认证函数
def cms_login(request):
    if request.method == 'GET': #进来请求如果是get,那么返回登陆界面
        return render(request,'cms_login.html')
    else:
        form = LoginForm(request.POST) #如果是post请求,通过表单LoginForm接受传入的request.POST字典对象
        if form.is_valid(): #如果表单的输入是有效的(密码规范,用户名长度等等)
            username = form.cleaned_data.get('username',None) #从表单清洗数据并获取获取username,password
            password = form.cleaned_data.get('password',None)
            user = authenticate(username=username,password=password) #这里使用authenticate帮我们完成数据库比对校验赋对象user
            if user and user.is_active: #如果对象存在,请用户是可用状态
                login(request,user)     #触发user对象登陆,做sessionid和user的关联
                nexturl = request.GET.get('next') #如果有下一步操作,记录这个操作,并在登陆后跳转回原来的操作界面
                if nexturl: 
                    return redirect(nexturl)
                else:
                    return redirect(reverse('cms_index')) #没有下一步的操作,就返回主页,通过reverse查找别名的url路由
            else:
                return render(request,'cms_login.html',{'errors':u'用户名或密码错误'}) #如user对象不存在,或者状态不可用,报错
        else:
            return render(request,'cms_login.html',{'errors':form.errors}) #如果传入的form表单格式有问题,也报错.

1.1使用user创建用户
首先需要导入模块
from django.contrib.auth.models import User
但是在python控制台,导入模块报错了

这是因为Ide的配置环境不是在纯粹的shell环境下,而是一个加了壳的shell环境.解决办法是重新设置环境变量.
import os,django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project_name.settings")# project_name 项目名称
django.setup()
如果上述步骤最后一步报错,按如下操作即可
>>> import sys
>>> sys.path.append('F:\\Project\\git\\web\\xtadmin') #F:\\Project\\git\\web\\xtadmin是项目目录
配置环境变量后,即可正确导

配置环境变量后,即可正确导入
>>> from django.contrib.auth.models import User
>>> u=User.objects.create(username='yangfan',password='123')
>>> u.save()
配置成功后,即可使用yangfan这个账号登陆.

1.2注销logout(request)
如果需要使用注销功能,需要导入模块from django.contrib.auth import logout

使用案例

#coding=utf-8
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth import logout
def index(request):
    if request.user:
        #logout(request) #未启动退出登陆
        print '当前登录的用户是:',request.user
    else:
        print '+++++'
    return HttpResponse( '当前登录的用户是:'+ str(request.user))

将注销logout(request)启用后,登陆用户变成了匿名

User模型常用属性和方法:
  • username:用户名。
  • email:邮箱。
  • groups:多对多的组。
  • user_permissions:多对多的用户权限。
  • is_staff: 是否是admin的管理员。
  • is_active: 是否激活,判断该用户是否可用。
  • is_superuser: 是否是超级用户。
  • last_login: 上次登录时间。
  • date_joined: 注册时间。
  • is_authenticated: 是否验证通过了。
  • is_anonymous:是否是匿名用户。
  • set_password(raw_password): 设置密码,传原生密码进去。
  • check_password(raw_password): 检查密码。
  • has_perm(perm): 判断用户是否有某个权限。
  • has_perms(perm_list): 判断用户是否有权限列表中的某个列表。

2.权限permission

要使用权限的话,需要在INSTALLED_APPS先启用django.contrib.contenttypes
  • contenttypes是管理认证,后台,是一个更高级的类型抽象,管理映射关系,使用何种用户,何种模型,如何关联起来,它都有牵线撘桥的作用.
2.1创建权限的方法
from myapp.models import BlogPost #BlogPost是需要创建权限的模型
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType #导入中间桥梁content_type = ContentType.objects.get_for_model(BlogPost) #使用get_for_model方法,将模型关联
permission = Permission.objects.create( #创建权限
    codename='can_publish',             #权限名称
    name='Can Publish Posts',           #权限的描述
    content_type=content_type,          #权限关联到对象
)
2.2权限关联到用户
ArticleModel模型定义了4个权限:
#cms/models.py
class ArticleModel(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    create_time = models.DateTimeField(null=True,auto_now_add=True)
    author = models.ForeignKey('AuthorModel',null=True)
    class Meta:            #定义一个元类
        # 1.看文章的权限
        # 2.修改文章的权限
        # 3.删除文章的权限
        # 4.发布文章的权限
        permissions = (              #定义存放权限的元祖
            ('watch_article',u'watch article'),  #每个权限对应的名称,描述
            ('update_article',u'修改文章的权限'),
            ('delete_article',u'删除文章的权限'),
            ('add_article',u'发布文章的权限'),
        )
        verbose_name='书籍'
        verbose_name_plural='书籍'
    def __unicode__(self):
        return self.title
现在需要将发表文章的权限add_article赋给用户laocao

通过控制台操作

>>> from article.models import ArticleModel
>>> from django.contrib.auth.models import User,Permission,Group
>>> from django.contrib.contenttypes.models import ContentType
>>> content_type=ContentType.objects.get_for_models(ArticleModel)#新增contenttype,关联数据库ArticleModel
>>> permission=Permission.objects.get(codename='add_article') #将权限add_article取出到permission
>>> u=User.objects.get(username='laocao') #获取用户对象
>>> u
<User: laocao>
>>> u.user_permissions.add(permission)  #使用user_permissions.add方法把权限赋给用户laocao
>>> u.save() #保存,查询有什么权限
>>> u.get_all_permissions()
set([u'article.add_article'])

权限增加成功了.代码实现的逻辑是:
  • 通过装饰器permission_required检查用户权限request.user_permission字典中是否有ariticle.add_article这个权限,如果有就执行下面的操作,否则就不执行
@permission_required('article.add_article') #使用装饰器,检查是否有增加文章的权限(前面赋值给了laocao)
def add(request):
    if request.method == 'GET':
        return render(request,'cms_add.html') #首次请求add,如果有权限,那么返回增加文章的界面.
    else:
        form = AddArticleForm(request.POST) #从取出前台传过来的包含文章标题,内容的字典对象,传给表单form
        if form.is_valid():
            title = form.cleaned_data.get('title',None)
            content = form.cleaned_data.get('content',None)
            articleModel = ArticleModel(title=title,content=content) #保存到数据库
            articleModel.save()
            return redirect(reverse('cms_index')) #返回主页
        else:
            return render(request,'cms_add.html',{'errors':form.errors}) #否则报错

3.策略组Group

当有多个用户要实现同样的权限时,单个操作并不是最好的办法,通过创造一个组,并把用户添加到组里是一个不错的方法.
  • 新增一个组xiaobian,将新增的用户fuyun添加到这个组,该组成员可以实现删除操作.
>>> u=User.objects.create_user(username='fuyun',password='123') #新建用户fuyun给u
>>> u.save()
>>> p=Permission.objects.get(codename='delete_article') #从权限中取出删除delete_article权限给p
>>> g=Group.objects.create(name='xiaobian') #新建用户xiaobian赋值给对象g
>>> g.permissions.add(p) #将删除权限p对象添加到xiaobian组里g
>>> g.user_set.add(u) #将用户fuyun添加到xiaobian组里
>>> g.save()
>>> g.permissions.all()
<QuerySet [<Permission: article | 书籍 | 删除文章的权限>]> #权限时放在xiaobian组里的
>>> u.user_permissions.all() #实际上,用户funyun没有个删除权限,而是继承了组里的删除权限
<QuerySet []>
登陆fuyun后,即可完成删除操作.

作业:

1.点击删除后,可以将文章从数据库中删除
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文章列表</title>
</head>
<body>
    <center>
    <h1>文章列表</h1>
    <p>当前登录的用户是{{ request.user }}&nbsp;<a href="add/">增加文章</a></p><table border="1" style="border-collapse: collapse">
        <tbody>
            {% for article in articlelist %}
                <tr>
                    <td>{{article.title}}</td>
                    <td>{{article.create_time}}</td>
                    <td>
                        <a href="edit/?id={{ article.id }}">编辑</a>&nbsp;|&nbsp;
                      <a href="delete/?id={{article.id}}">删除</a> 
                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
  </center>
</body>
</html>
视图函数delete实现的逻辑
  • 通过前端传过来的id
  • 通过id查询对应的文章记录
  • 通过id删除
def delete(request):
    id=request.GET.get('id')
    p=ArticleModel.objects.filter(id=id).first()
    title=p.title
    p.delete()
    return HttpResponse(u'文章<<%s>>已经被删除'%title)
2.点击编辑后,可以修改文章,并保存到数据库
往模板中增加一个编辑的页面
#cms_edit.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>编辑文章</title>
</head>
<body>
    <h1>编辑文章</h1>
    <table>
        <tbody>
            <form method="post">
                {% csrf_token %}
                <tr>
                    <input type="hidden" name="id" value="{{ id }}"/>
                    <td>标题:</td>
                    <td><input type="text" name='title'value="{{ title }}"></td>
                </tr>
                <tr>
                    <td>内容:</td>
                    <td><textarea name="content" id="" cols="30" rows="10">{{ content }}</textarea></td>
                </tr>
                <tr>
                    <td></td>
                    <td><input type="submit" value='提交'></td>
                </tr>
            </form>
        </tbody>
        <p>
            {% if errors %}
                {{errors}}
            {% endif %}
        </p>
    </table>
</body>
</html>
从edit中渲染
  • 如果请求是get,则从数据库中取出对应的id的记录
  • 将记录渲染到编辑模板页面
  • 文章被修改后,通过post请求提交表单
  • 入库成功后,返回文章列表页面
def edit(request):
    if request.method=='GET':
        id=request.GET.get('id')
        p=ArticleModel.objects.filter(id=id).first()
        return render(request,'cms_edit.html',{'id':id,'title':p.title,'content':p.title})
    else:
        id=request.POST.get('id')
        p=ArticleModel.objects.filter(id=id).first()
        p.title=request.POST.get('title')
        p.content=request.POST.get('content')
        p.create_time=datetime.datetime.now()
        p.save()
        return redirect(reverse('cms_index'))

总结

Django的auth认证系统是非常实用的模块,包含了用户,权限,组.属于比较难理解和掌握的部分,涉及到知识面更要求综合性,熟悉掌握对于开发维护有很大帮助.
赞(0)
未经允许不得转载:http://www.yueguangzu.net逗逗网 » [Django系列]14.Django的auth认证系统
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址