BBS项目(二): 登录功能 首页导航条搭建 首页主体部分 个人站点页面搭建 文章分类与标签 日期归档

登录功能

pillow模块生成验证码

创建画笔对象:

image-20230103094159864

用pillow模块写字还需要ttf字体文件。
去网上下载ttf字体文件:

https://www.fonts.net.cn/font-41698350290.html
https://font.chinaz.com/

确定字体样式:

image-20230103094336783

truetype函数:
image-20230103094300121

编写随机验证码相关代码:
image-20230103094641455

将随机验证码写到图片上:
image-20230103094723585

text第一个参数表示的是写字的位置(以左上角为标准):
(x, y)

后端保存验证码,便于后续比对:
验证码数据要在不同的函数使用,等会要在login函数使用。所以需要找一个所有人都能访问的地方。

image-20230103095005088

1.全局变量
2.session表

实现验证码点击之后刷新:
原理:img标签的src属性的服务器路由发生变化时(使用?加参数),img标签会重新发送get请求。

image-20230103095657471

前端发送ajax请求

form标签序列化功能:

image-20230103100103672

但是这个功能这种情况不适用,还是依次获取输入框的数据:
image-20230103100321693

后端auth模块校验

image-20230103100706007

比对验证码、比对用户名和密码。
注意:忽略验证码的大小写

auth模块自动加密,然后拿密文进行比对:
image-20230103100804490

登录成功后跳转到首页。

前端回调函数:
image-20230103101152813

sweetalert弹窗提示登录失败

image-20230103101000246

可以使用sweetalert美化弹窗。
官网:https://sweetalert.js.org/
使用参考:www.cnblogs.com/Dominic-Ji/p/9234099.html

后端保存用户登录状态:

image-20230103102034094

首页导航条搭建

网站首页路由:
image-20230103101447497

修改bootstrap导航条:

image-20230103101807728

添加注释:
image-20230103103652556

反向解析:
image-20230103102124815

判断当前用户是具体用户还是匿名用户,返回true或者false:
image-20230103102252911

根据是否登录展示不同的功能:
image-20230103102332672

修改密码

点击修改密码,触发模态框:
image-20230103103724521

研究模态框:
image-20230103103839564

发现按钮的data-toggle属性和data-target属性跟模态框有关。

修改模态框文本内容:
image-20230103103945129

在模态框内部使用ajax:
image-20230103104423247

设置disable仅仅展示用户名,不让用户修改。

给按钮绑定点击事件:
image-20230103104659926

添加修改密码的路由:

修改密码的视图层:
校验用户是否登录装饰器
导入auth模块:
image-20230103104559519

image-20230103104610016

settings配置:
image-20230103104628257

前端获取数据:
image-20230103104828180

后端修改密码逻辑:
image-20230103104957785

校验原密码是否正确:
image-20230103105258746

避免新密码和二次输入密码是空:

image-20230103105235573

注意保存:
image-20230103105704787

正确情况逻辑编写完成,补上错误情况的后端逻辑:
image-20230103105423132

前端在模态框加一个标签提示修改成功:

image-20230103105517941

前端回调函数:
image-20230103105534973

效果:

image-20230103105603106

注意:修改密码之后,登录状态会消失,需要重新登录。

退出登录

开启新路由:
image-20230103105808596

前端绑定路由:image-20230103105914569

添加装饰器:
image-20230103105825258

使用auth模块的退出功能,退出登录后跳转到首页。

首页主体部分

首页前端框架搭建

模仿博客园:
image-20230103110042589

前端282布局:
image-20230103110103962

广告样式编写:
使用面板(样式为panel-primary):
image-20230103110210807

首页左侧右侧广告位:
image-20230103110342320

首页中间区域展示文章内容。此时需要先往数据库录入一些数据。

此时不建议用django连接数据库录入数据,因为表之间的外键关系复杂,数据录入错误(或者外键关系绑定错误)会导致用户信息错乱(用户A的站点显示用户B站点的文章)

此时数据录入工具使用:django admin后台管理

admin后台管理使用

需要使用到超级管理员。所以先要创建一个管理员账号

需要修改admin.py:

image-20230103110914746注册想操作的模型表。

image-20230103110807272注意:admin.py 每个app都有一个。

注册完成之后,django针对你注册的表,会自动生成增删改查功能(图形化界面):

注册所有模型表:

image-20230103111012420

查看后台管理:
image-20230103111027982

模型表的名字 尾部都会自动添加s。
修改admin后台为中文:
去模型类添加代码:
image-20230103111136608

这个代码和数据库没有联系,无需迁移数据库。
查看admin后台:
image-20230103111235092

数据录入

表直接关系复杂,直接录入容易错误,所以使用admin后台进行添加。

绑定错误会导致用户信息错乱。
我登录,访问的是别人的站点。

入手 --- 文章表:
image-20230103111428642

父子页面通信:
image-20230103111503650

先录入站点 和 分类:

站点:
image-20230103111619430

显示问题:
image-20230103111751683

这里就需要加双下str:
image-20230103111840391

查看效果:
image-20230103111958151

添加分类:
image-20230103112034266

添加文章:
image-20230103112203683

查看文章:
image-20230103112342173

绑定用户表:

用户绑站点别忘了image-20230103112428160

会报错,报错原因:

报错是因为admin后台有字段没填写。image-20230103112453001

这是数据库层面的约束。
所以可以也让后台管理不写:
image-20230103112534611

分类:
文章和标签:
创建标签:
image-20230103112628439

文章标签绑定:
注意用户1的文章 要和 用户1的标签绑定:
image-20230103112800586

这里不同人的文章是放一起的,别弄错。

首页查询数据库文章

添加分页器:
image-20230103113039473

导第三方py文件:

image-20230103113123605

分页器产生页面对象:
image-20230103113237465

对页面对象进行切片。

前端渲染文章:

image-20230103113307381

bootstrap媒体对象:
image-20230103113327321

修改媒体对象:
image-20230103113411999

image-20230103113502441

文章标题应该a标签 头像位置调整
头像下面展示用户名 文章发布时间 点赞点踩

修改媒体对象:
image-20230103113632734

分割线:
image-20230103113751723

渲染用户名 文章发布时间 点赞点踩:
image-20230103113914969

整体样式调整:
image-20230103114635647

上下分页器添加:
image-20230103115225521

media自定义暴露资源

不只是静态文件,可以暴露后端的任意资源供访问。
修改src为数据库存放的avatar路径:
image-20230103115632725

浏览器查看:
image-20230103115709224
查看原因:
image-20230103115724566

是因为没有开启avatar路径的访问权限!
media 配置:
用户写博客穿插图片,这些图片属于静态资源。
需要给用户存放,用户上传的静态文件资源。

查看博客园:
image-20230103120009619

希望用户上传的东西,都存放在同一个目录下,然后再进行具体划分。

修改settings文件:
image-20230103120132438

这个目录会自动创建。

注册新用户:
image-20230103120245576

用户上传的文件会 存到media

然后根据模型表字段的限制,会自动在media生成相应的目录:

image-20230103120313632

暴露后端的任意资源供访问:
不是静态文件暴露,需要路由层写接口:
还要导入模块。
image-20230103120537959

使用re_path:
image-20230103120843407

第三个参数写配置文件的Media路径(导入settings)。

需要字典,否则会报错:
image-20230103120823830

浏览器访问示例:

image-20230103120909244

此时media目录就已经暴露出来了。

修改前端页面:image-20230103120943820

此时media目录下的所有文件都可以访问了。

还可以暴露其他的目录:

image-20230103121031695

意味着用户可以访问你写的代码:
image-20230103121052368

访问示例:
image-20230103121116498

不要暴露不该用的东西,会有安全风险。

作业:
用户登录成功之后 显示用户头像。

个人站点页面搭建

路由动态匹配 后端简单逻辑

实现点击用户名 跳转到个人站点。

查看博客园如何实现需求:
image-20230103121437103
发现路由里面包含用户的名字。

先开路由,需要使用动态匹配:

image-20230103121607464

注意:别忘了加斜杠。

后端编写:

image-20230103121749045
判断个人站点是否存在,如果不存在跳转到404页面。

404页面

image-20230103121657873

后端逻辑:
image-20230103121933322

复制博客园404页面:
image-20230103121859887

图片防盗链技术

从别的网站复制过来的页面,经常会出现图片无法加载的现象。这是因为使用了图片防盗链技术。

image-20230103122037739

禁止通过拷贝图片地址 就直接拿到网站的图片。
服务器先问你是从哪里来的,如果是从别的地方来的就不给你图片。
referer键值对 存放你是从哪来的信息:
image-20230103122240113

我们网站的请求头referer参数:

image-20230103122257734

来自博客园的请求头referer:
image-20230103122324275

解决方案:

  1. 编写图片下载脚本,将图片下载到本地使用。
  2. 在请求头加referer参数。(写爬虫程序的时候添加)

页面主体初搭建

基于个人站点查询站点下的文章:
image-20230103143435526

站点页示例:(使用2、10布局)
image-20230103143517633

后端逻辑编写:
image-20230103143543016

前端使用模板继承:

  1. 母板区域划分
    image-20230103143656213

  2. 子板继承:
    image-20230103143841703

子板代码编写(布局2):
image-20230103144120894

子板代码编写(布局10)主体内容区:
image-20230103144254020

前端样式修改:
将用户名移动到右边去:
image-20230103144538399

效果展示:
image-20230103144622705

主体部分细节补充

分页器添加:
分页器添加和首页操作一致,不再赘述。后端导入第三方代码,生成页面对象,切片传入前端,在前端使用模板语法for循环渲染即可。

首页用户名a标签路由添加:(实现点击用户名跳转到个人站点的功能)
image-20230103144739873

模拟用户上传css js的代码:
image-20230103144900099

前端根据用户上传的css文件动态加载css样式:
image-20230103145018864

个人站点侧边栏功能完善

需求:
image-20230103145256322

文章分类

拿到当前个人站点下所有分类名称:
image-20230103145514913

统计每个分类下的文章:
使用分组查询。
annotate左边没有values 就按照文章分组。
value后面加annotate可以按照字段分组。

导入聚合函数:

image-20230103145910965

分类查文章(反向查询):

image-20230103150014742

ORM:
image-20230103150033601

查看结果:
image-20230103150110221

前端页面编写(使用category_queryset后端传来的名字):
image-20230103150327889

分类的筛选功能:通过点击文章分类获取该分类下的所有文章。(未实现)

文章标签

查询个人站点下所有的标签名称,以及标签的文章数:

image-20230103165049776

标签前端渲染(使用tag_queryset后端传来的名字):
image-20230103150651605

日期归档

按照年月给文章分组。

我们存储的是年月日时分秒:
image-20230103150929367

orm关于按照字段分组的额外操作:

官网提供查询代码 annotate

由于分组之后再使用聚合函数已经无法满足我们的需求,所以可以使用官网提供的查询代码。

官网提供了针对日期字段的切割处理

id  content      create_time     month
1   111        2020-11-11     2020-11
2   222        2020-11-12     2020-11
3   333        2020-11-13     2020-11
4   444        2020-11-14     2020-11
5   555        2020-11-15     2020-11
"""
django官网提供的一个orm语法
 from django.db.models.functions import TruncMonth
-官方提供
   from django.db.models.functions import TruncMonth
   Sales.objects
   .annotate(month=TruncMonth('timestamp'))  # Truncate to month and add to select list
   .values('month')  # Group By month
   .annotate(c=Count('id'))  # Select the count of the grouping
   .values('month', 'c')  # (might be redundant, haven't tested) select month and count
   
   
时区问题报错
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
"""

节选年月:
表中会凭空多一个虚拟字段。也就是按照年月分组的新字段。

annotate 分组 、处理字段
相同的单词放在不同的位置,有不同的意思:
image-20230103151335431

导模块:
image-20230103151517768

不仅可以创建年月字段 还可以创建更多不同类型的虚拟字段

创建虚拟字段:
image-20230103151617212

查看查询结果:
image-20230103151655961

可能会报错:
image-20230103151724127

时区问题

报错信息里面有time zone,往往是时区问题

修改时区为自己本地:
image-20230103151843268

上面的ORM漏了一个查询:
image-20230103151937588

查看ORM查询结果:
image-20230103152013776

前端页面展示年月数据:
image-20230103152129284

代码

链接:https://pan.baidu.com/s/1cXgoRwv_POS1gZ8HFpFMrw
提取码:u9x9

posted @ 2023-01-03 17:19  passion2021  阅读(129)  评论(0编辑  收藏  举报