Auth的补充
#概念:是django 的一个app,关于用户的登录,退出,注册...
# 配置文件中配置:表会被迁移INSTALLED_APPS = [ 'django.contrib.auth', ]
# auth有哪些表---权限控制:
Permission:auth_permission Group:auth_group User:auth_user --->密码加密 auth_group_permissions auth_user_groups auth_user_user_permissions
# 目前阶段只用 auth_user来做用户的一些操作
# 如果用户没登录:
request.user取出的是匿名用户:
AnonymousUser类的对象,也有pk,name,is_authenticated
# 模块常用方法:
1 user = authenticate(username='usernamer',password='password')# 校验用户:必须传username和password user = authenticate(username='usernamer',password='password') from django.contrib.auth.models import User user=User.objects.filter(username=username).first() if user and user.check_password(password): print('用户名密码正确') else: print('用户名密码错误')
2 login:用户校验通过,让它登录,执行它
-当前登录用户写入到session中
-后续 request.user 就能拿到当前登录用户auth.login(request, user) user=request.user
3 logout:退出,清空session
4 request.user.is_authenticated:返回True或False
5 login_requierd :登录认证装饰器,放在视图函数上 ,会重定向
@login_required(login_url='/login/')
6 create_user:普通用户
-User.objects.create()--密码是加密的---》这样存密码是明文的
7 create_superuser:超级用户 python38 manage.py createsuperuser8 check_password :通过明文密码校验密码是否正确
9 set_password:修改密码user.set_password(new_password) user.save()
10 User对象的属性:
username
password
is_staff : 用户是否拥有网站的管理权限,能不能登录admin后台管理
is_active: 是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录
is_active是False----authenticate也查不出来
is_superuser:是否是超级管理员,admin中权限最高# auth模块的密码加密:同样的密码--》再次加密--》密文也不一样
pbkdf2_sha256$ # 加密方式
260000$ #过期时间
H93ubuUFw6FbYc6B8ojzKA$ # 随机串,,秘钥
H0ZnaiJOm/pI4K802Y2TcO5SQ7iWDcx5E+mb/hdABd8= #明文加密后的
# 后期如果你自己写了User表,但是想用人家的密码加密,就可以使用res=make_password('123456') check_password(明文,密文)
扩写auth的user表
# 第一种方案:通过一对一扩展(基本不用)
from django.contrib.auth.models import User class UserDetail(models.Model): user=models.OneToOneField(to=User) phone=models.CharField(max_length=32)
# 第二种:通过继承 AbstractUser表来扩写
1、在models.py中写用户表from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): # 原来有的字段就不需要写了,只需要扩写你想写的字段 mobile=models.CharField(max_length=32) icon=models.ImageField(upload_to='/icon/',default='default.png') # 路径和默认值
2、在settings.py 配置
AUTH_USER_MODEL='app名字.表名' # 不区分大小写 AUTH_USER_MODEL='app01.UserInfo'
3、之前不要迁移数据,一旦迁移过,就不行了
一旦迁移过了,按这个步骤操作:
-1 删库
-2 删迁移文件(所有你写的app都删)
-3 删除源码中 auth和admin的迁移文件---》写在djagno重装
缓存
# 概念:缓存又称页面静态化, django 默认就支持缓存
# 原由:本身数据在数据库中,如果访问量较大,每次都需要去数据库查询,影响效率。可以对数据做缓存,以后先从缓存中取数据
如果取到:直接返回,不需要查数据库
如果取不到:再查数据库,查完放到缓存中
# 缓存到的位置:
内存缓存(演示)
文件缓存
数据库缓存
redis缓存(后期会用)
# 默认情况,缓存到内存中CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } }
# 缓存到文件中
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎 'LOCATION': 'D:\pythonproject\huancun_file', #指定缓存的路径 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }} }
# 缓存的具体使用:三种粒度
1 全站缓存:只需要置两个中间件即可
2 视图缓存
3 局部缓存:在页面某个位置缓存
# 全站缓存,使用方式-如下-只需要配置中间件即可MIDDLEWARE = [ 'django.middleware.cache.UpdateCacheMiddleware', ... 'django.middleware.cache.FetchFromCacheMiddleware' ]
# 视图缓存
from django.views.decorators.cache import cache_page @cache_page(timeout=10) def demo09(request): print('来了老弟') book_list = Book.objects.all() return render(request, 'books.html', {'books': book_list})
# 局部缓存
{% load cache %} {% cache 10 'name' %} 可以能有很多代码 {% endcache %}
项目开发流程
项目立项——公司高层定的
需求调研和分析-——市场人员,技术人员
需求文档 说明
开发部门开会——确定项目架构,技术选型,数据库设计
ui,ud团队(产品经理)——原型图---切图--交给前端
分任务开发:
-前端
-后端:对着原型图--》设计--》设计数据库,设计功能
前后端联调
提交版本——测试
发布上线
BBS项目功能
1、注册功能:校验
ajax注册
头像显示和上传
2、登录
3、首页文章显示(分页---》自己加上)
4、个人站点:显示这个人写的所有文章
侧边栏有分类,标签,随笔档案
5、文章详情
6、点赞,点踩
7、评论:根评论
子评论
8、后台管理:查看所有文章
删除文章
新增文章:xss攻击去除
设计数据库
1 用户表 UserInfo--->扩写auth的user表
2 博客表 Blog--->跟用户表做一对一关联
3 文章表 Article
4 文章分类表 Category
5 标签表 Tag
6 点赞点踩表 UpAndDown
7 评论表 Commit# 关联关系:
用户和博客 : 一对一
博客和文章: 一对多 一个博客下,有很多文章,关联字段写在文章表中
博客和分类: 一对多 一个博客下,创建多个分类,关联字段写在分类表中
博客和标签: 一对多 一个博客下,创建多个标签,关联字段写在标签表中文章和分类: 一对多 一个文章只能属于一个分类,一个分类下有很多文章
文章和标签:多对多 一个文章可以有多个标签,一个标签下可以有多个文章点赞和用户:一对多 一个用户可以点很多赞,一个用户可以点很多赞
评论和用户:一对多 一个用户可以评论多个,评论的一条记录只属于一个用户文章和点赞:一对多 一篇文章,可以被点多次,但是一个点赞的记录只对应一篇文章
文章和评论:一对多 一篇文章,可以被评论多次,但一个评论的记录只对应一篇文章
setting文件配置
# 解释器环境中有 djagno ==3.2.20
# 1 国际化:LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
# 2 配置了static
STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
# 3 配置了media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'
# 4 配置了链接mysql
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'blog', 'USER': 'root', 'PASSWORD': '1234', 'HOST': '127.0.0.1', 'PORT': 3306 } }
创建项目迁移表
1 用户表 UserInfo---》扩写auth的user表
2 博客表 Blog---》跟用户表做一对一关联
3 文章表 Article
4 文章分类表 Category
5 标签表 Tag
6 点赞点踩表 UpAndDown
7 评论表 Commitmodels.py from django.db import models from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): # 扩写字段---》手机号,头像, phone = models.CharField(max_length=32) # /media/avatar/default.png # 必须安装pillow 才能使用 ImageField avatar = models.ImageField(upload_to='avatar', default='avatar/default.png') blog = models.OneToOneField(to='Blog', on_delete=models.CASCADE, null=True) class Meta: verbose_name_plural = '用户表' # 给其他人看,知道这是用户表 def __str__(self): return self.username class Blog(models.Model): # 博客标题 site_title = models.CharField(max_length=32) # 博客副标题 site_name = models.CharField(max_length=32) # 博客样式 # 每个人样式不同(文件地址) site_style = models.CharField(max_length=32) class Meta: verbose_name_plural = '博客表' def __str__(self): # 会报错 try: return self.userinfo.username + '---' + self.site_title except Exception as e: return self.site_title class Tag(models.Model): name = models.CharField(max_length=32) blog = models.ForeignKey(to=Blog, on_delete=models.SET_NULL, null=True) class Meta: verbose_name_plural = '标签表' def __str__(self): return self.name class Category(models.Model): name = models.CharField(max_length=32) blog = models.ForeignKey(to=Blog, on_delete=models.SET_NULL, null=True) class Meta: verbose_name_plural = '分类表' def __str__(self): return self.name class Article(models.Model): title = models.CharField(max_length=128) # 文章摘要 desc = models.CharField(max_length=256, verbose_name='文章摘要') # 文章详情 大文本 content = models.TextField() create_time = models.DateTimeField(auto_now_add=True) # 关联字段 # 标签和分类 category = models.ForeignKey(to=Category, on_delete=models.SET_NULL, null=True) # 多对多,手动创建中间表 tag = models.ManyToManyField(to=Tag, through='ArticleToTag', through_fields=('article', 'tag')) # 博客 blog = models.ForeignKey(to=Blog, on_delete=models.CASCADE) class Meta: verbose_name_plural = '文章表' def __str__(self): return self.title class ArticleToTag(models.Model): article = models.ForeignKey(to=Article, on_delete=models.CASCADE) tag = models.ForeignKey(to=Tag, on_delete=models.CASCADE) class UpAndDown(models.Model): user = models.ForeignKey(to=UserInfo, on_delete=models.CASCADE) article = models.ForeignKey(to=Article, on_delete=models.CASCADE) is_up = models.BooleanField(default=True) create_time = models.DateTimeField(auto_now_add=True) class Meta: verbose_name_plural = '点赞点踩' def __str__(self): return self.is_up class Commit(models.Model): user = models.ForeignKey(to=UserInfo, on_delete=models.CASCADE) article = models.ForeignKey(to=Article, on_delete=models.CASCADE) content = models.CharField(max_length=256) create_time = models.DateTimeField(auto_now_add=True) # 自关联,评论层级---》子评论 一定要写null=True parent_id = models.ForeignKey(to='self', on_delete=models.CASCADE, null=True) class Meta: verbose_name_plural = '评论表' def __str__(self): return self.content
# 自关联:
注册功能案例
完成注册功能---高级一些使用form
-头像实时显示
-注册失败错误信息展示
-注册成功跳转到登录页面
测试三种缓存粒度
全站缓存:
1、缓存在文件中:
setting.py MIDDLEWARE = [ # 全栈,两个中间键 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'app01.middle_key.MyMiddlew', 'django.middleware.cache.FetchFromCacheMiddleware' ] CACHES = { # 存在文件中 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎 'LOCATION': 'D:\pythonproject\huancun_file', #指定缓存的路径 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300) 'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
views.py # 全站缓存 from .models import Data def demo09(request): print('你好,周佳佳') data=Data.objects.all() return render(request,'shuju.html',{'data':data})
shuju.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="bd-example"> <table class="table table-striped"> <thead> <tr> <th>id</th> <th>书名</th> <th>价格</th> <th>出版社</th> </tr> </thead> <tbody> {% for book in data %} <tr> <th scope="row">{{ book.id }}</th> <td>{{ book.username }}</td> <td>{{ book.email }}</td> <td>{{ book.password }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
2、缓存在内存中,看不见
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } }
视图缓存:
views.py from .models import Data from django.views.decorators.cache import cache_page @cache_page(timeout=10) def demo09(request): print('你好,周佳佳') data=Data.objects.all() return render(request,'shuju.html',{'data':data})
局部缓存:
html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"></script> </head> {% load cache %} <body> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="bd-example"> <table class="table table-striped"> <thead> <tr> <th>id</th> <th>书名</th> <th>价格</th> <th>出版社</th> </tr> </thead> <tbody> {% for book in data %} <tr> <th scope="row">{{ book.id }}</th> <td>{{ book.username }}</td> <td>{{ book.email }}</td> <td>{{ book.password }}</td> </tr> {% endfor %} </tbody> </table> {% cache 1 'name' %} <hr> {{ time }} {% endcache %} </div> </div> </div> </body> </html>
views.py # 视图缓存 from .models import Data import datetime def demo09(request): print('你好,周佳佳') data=Data.objects.all() return render(request,'shuju.html',{'data':data,'time':str(datetime.datetime.now())})
bootstrap5 的使用
使用bootstrap5 美化注册页面
下载 -Bootstrap中文网
# CSS引入 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"></script>