
一直潜心学习后端知识的我,在得到学校最后的可视化实验竟然是用前端做可视化网页,我当场就是黑人问号,于是不得暂时放弃期末复习而去学习html,css,js的知识。学习视频来源于b站上的视频(点击跳转视频),老师讲基础讲的很好,把前端知识,mysql,django分为3个部分讲解,在我1天8小时的肝度下,3天后终于学会了基础的前端知识和django的运转原理。实验所用到数据是2020年2月的疫情数据,都是死数据,而且是借鉴了大佬点击跳转的sql语句设计和echarts可视化,因此不会讲到太多关于sql的部分。
1.项目的搭建使用到的Django版本为3.2.13,python版本为3.7。
首先是搭建django项目,可以使用命令,也可以在pycharm中直接创建,我使用的是后者
然后我们就会看到项目文件夹下出现了这些文件
我一般会删除自动生成的templates,然后再将setting中将templates的默认路径删除掉
再将csrf令牌服务注释掉
我个人会比较喜欢创建一个app来管理功能,由于只是一个小项目,就只创建一个app来管理:在终端中输入命令
执行完成后就能看到我们的app被创建了
创建app后就马上去下面的主体部分中的settings.py中注册app
然后在web(创建的app)文件夹下创建static,templates,utils文件夹,再在static下创建css,img,js,plugins文件夹。
下面画一个架构图说明这个运作原理:
下面可以试试最简单的运转,在urls中导入web下的views,然后添加一个ulr地址
然后去web下的views中写入对应的函数:
html的名称可以随便取,这里为了对应,我同样也写了test这个名称。然后我们取templates下创建一个test.html,随便写入一点内容
然后启动django项目,在终端中输入在这 python manage.py runserver
点击下面的超链接
这里由于我们给这个test.html的地址配置的是/test,所以还需要在网址后面加上/test,这里也是提示我们有两个地址可以选择:admin和test,admin是django自带的登录网页,后面的test就是我们设置的网页。下面我们加上/test:
可以看到也是成功的访问了这个页面,那么到此项目的基本搭建就已经完成了。
既然是一个系统,那登录注册功能肯定是少不掉的,和上面的步骤一样,先在urls中添加登录的地址
在views中写出函数
最后在templates中添加login.html。那我们直接开始编辑html,由于我只学了基础的知识,那些什么炫酷的动态例如反转,滑动特效我是写不出的。只能写个尽量简洁好看的界面,而且我写的代码可能也会有一些不合理导致看起来很冗余
那就是常见的这种布局了:
再实现之前,我们先引入插件bootstrap和js插件jquery
然后在html最上方写一个这个
它是django提供的语法,可以帮助我们更好的写路径,那我们就导入插件,css进来
注意导入的位置,js插件最好是放在body中的最下面,而bootstarp的js又要依赖于jquery,所以要先让jquery导入
然后先初步的画出布局,通过中的内容来调整样式,下面div标签中对应的class名为login_box,style中就可以相应的建立一个.login_box{}来调整样式
{% load static%}
Title
用户登录
接下来我们直接使用bootstrap中提供的表单样式
放到h1下面一行就行
那么我们只用的上输入框和按钮,把不要的删除即可。到这里布局就基本完成,下面就只是美化了,美化就不是一言两语讲的清楚的了,而且每个人的审美设计也不一样。再加上这里的演示我是完全新建了一个html,我在下面贴出基于这个布局的美化完了的html(里面也写满了注释):
{% load static %}
Title
{# 最外层的div,用于放整个登录窗口#}
{# 标题#}
用户登录
{# 提交表单的请求方式为post,对于之后区分登录和验证时会有帮助#}
{# 注册#}
{# 点击注册就会跳向注册的页面#}
没有账号?注册
现在我们回到后端,首先认识一下get和post请求,访问这个网页的本质就是向后端发出请求,我们输入网址是不是基本是https开头的超文本链接,这就是字符串请求,后端会解析收到的字符串,请求后执行上面我画的运转图的过程,发送html(本质就是一堆字符串)给浏览器,然后浏览器会解析字符串中的内容,再将其展示给用户看。而最常见的请求就是get请求,例如这个登录界面,在你输入完账号密码后点击submit类型(提交表单中数据)的按钮后,会将其显示在这里然后传给后端。而post就是“偷偷”的传给后端。
那我们完全可以这样设计,当用户提交普通的get请求时就显示这个页面,而当用户在这个页面点击了登录按钮触发了post请求(可以找到上面html中唯一的form标签后面是否被我加了一份method=‘post’)就会经过后端的一系列验证后跳向其他的页面。基于这种思路:
def login(request):
"""登录界面"""
# 如果请求是get就会正常的得到登录页面
if request.method == "GET":
return render(request, "login.html")
# 其他的请求,这里其他的请求我们基本使用的是post,也就是表单提交数据时发送的请求
else:
return render(request, 'test.html')
你可以试试在form后面加上method=‘post’,点击按钮后是否会解析出test.html。这样做后你可能会发现上面的url并没有变成/test,仍然还是https://blog.csdn.net/login,我们将render(request, 'test.html')换成redirect('/test') redirect是重定向。
2.1.2后端逻辑下面我们来解决如何验证用户账号,密码的问题:
得到form提交上来的数据只需要使用request.POST.get("html中input的name"),看向我们的html,给他加上一个name
views函数中加上这一句
然后再次输入内容提交看看
这样在后端我们就能看见了,现在我也要做的是把它和我数据库中账号,密码作比较
对于登陆和注册我是使用了django自带的服务,先在settings中修改数据库配置:
终端中输入命令绑定你的数据库
此时会生成一个models文件
每一个类就是一张表,我只会用到userinfo这张表,就只复制这个类到web下的models中
这样再将models导入views中from web import models,在views中我们只需要这样就能操作数据库中的这张表了models.UserInfo.objects.想做的操作。比如说models.UserInfo.objects.filter(username=x)就会寻找x是否在表的username这一列中,没有就返回空。最后我们再学习一个从后端传值给前端的方法,
在html中只要https://blog.csdn.net/qq_53500716/article/details/{{ 键名 }}(不用带引号)这样就能得到传过来的值了,你也可以查看上面我的html代码
最后就是我写的登录函数,也是写满了注释:
def login(request):
"""登录界面"""
# 如果请求是get就会正常的得到登录页面
if request.method == "GET":
return render(request, "login.html")
# 其他的请求,这里其他的请求我们基本使用的是post,也就是表单提交数据时发送的请求
else:
# 分别得到用户输入表达中的数据,get里面是找name的写法
user_login = request.POST.get("user")
pwd_login = request.POST.get("pwd")
yzm_login = request.POST.get("yzm")
# 对比数据库用户名,最好使用filter而不是get
user_db = models.UserInfo.objects.filter(username=user_login)
# 先对比用户名再对比密码,同样也是使用filter
pwd_db = models.UserInfo.objects.filter(username=user_login).filter(password=pwd_login)
# 如果用户存在
if user_db:
# 如果密码正确
if pwd_db:
# 如果验证码正确,下面的验证码函数中,验证码的数值被放入了session中
if request.session.get("image_code") == yzm_login:
# 全部满足后重定向至过度页面
return render(request, "interim.html", https://blog.csdn.net/qq_53500716/article/details/{"prompt1": "登录", "prompt2": "平台", "link": "/canvas"})
# 下面则是各种错误不同后的设置,会将设置好的字符串传入给网页
else:
msg = '验证码错误'
return render(request, "login.html", https://blog.csdn.net/qq_53500716/article/details/{"msg3": msg})
else:
msg = '密码错误'
return render(request, "login.html", https://blog.csdn.net/qq_53500716/article/details/{"msg2": msg})
else:
msg = '用户不存在'
return render(request, "login.html", https://blog.csdn.net/qq_53500716/article/details/{"msg1": msg})
传参数的效果,输入错误后,这里写的比较简单,所以不会再把之前用户填的数据放上去
那个数字验证码就不说了,大佬们写的开源的一堆。
2.2注册 2.2.1布局我的注册页面也是基于登录界面,就改了一点点东西
html源码就不放出来了,和登陆的差不多。
和登录的也是差不多,看注释就能看懂
def register(request):
"""注册界面"""
# 如果请求是get就会正常的得到登录页面
if request.method == "GET":
return render(request, "register.html")
# 其他的请求,这里其他的请求我们基本使用的是post,也就是表单提交数据时发送的请求
else:
# 分别得到用户输入表达中的数据,get里面是找name的写法
user_re = request.POST.get("user_re")
pwd_re = request.POST.get("pwd_re")
pwd_re_se = request.POST.get("pwd_re_se")
# 查找数据库中是否已存在用户名,最好使用filter而不是get
user_db = models.UserInfo.objects.filter(username=user_re)
# 如果用户名存在则传入已存在的错误信息
if user_db:
msg = '用户名已存在'
return render(request, 'register.html', https://blog.csdn.net/qq_53500716/article/details/{"msg1": msg})
# 如果用户名不存在
else:
# 输入的用户名不为空
if user_re:
# 输入的密码不为空
if pwd_re:
# 确认密码一致
if pwd_re == pwd_re_se:
# 将数据写入至data数据库中userinfo表中
models.UserInfo.objects.create(username=user_re, password=pwd_re)
# 重定向至确认界面
return render(request, "interim.html", https://blog.csdn.net/qq_53500716/article/details/{"prompt1": "注册", "prompt2": "登录", "link": "https://blog.csdn.net/login"})
# 下面则是各种错误不同后的设置,会将设置好的字符串传入给网页
else:
msg = '密码输入不一致'
return render(request, "register.html", https://blog.csdn.net/qq_53500716/article/details/{"msg3": msg})
else:
msg = '密码输入为空'
return render(request, 'register.html', https://blog.csdn.net/qq_53500716/article/details/{"msg2": msg})
else:
msg = '用户名输入为空'
return render(request, 'register.html', https://blog.csdn.net/qq_53500716/article/details/{"msg1": msg})
2.3过渡界面
最后是一个用于确认登录,注册成功的界面
views中函数(别忘记添加到路由中)
def interim(request):
"""过渡网页"""
return render(request, "interim.html")
网页代码
{% load static %}
Title
https://blog.csdn.net/qq_53500716/article/details/{{ prompt1 }}成功!点击https://blog.csdn.net/qq_53500716/article/details/{ link }}>确认跳转到https://blog.csdn.net/qq_53500716/article/details/{{ prompt2 }}界面...