关于前后端参数传递问题,欢迎移步我的文章
koko可可:Django从入门到大作业:3-前后端传参zhuanlan.zhihu.comDjango与Java Web最最最最最不同的地方,就是ORM(Object Relational Mapping)。对Django中所有数据表列元素的操作,都可以映射到某个Object上,实现整个项目零SQL。换言之,这种操作最大的好处,就是你可以无限更换底层数据库,而不用考虑代码问题。
细心的你,可能发现,从项目创建之初,就出现了一个名叫db.sqlite3
的文件。Django自带轻量级数据库SQLite,这免去了你安装其他数据库的烦恼。
如果只是为了实现华而不实的大作业,SQLite足够了,但如果项目在其他方面有需求,建议一开始就更换底层数据库。(虽说ORM将后端与SQL分离,但更换完数据库总是会出现玄学bug,尽早更换数据库,避免后期一蹶不振的情况,这简直是我的血泪史)
1. 创建user表
牢记:user表=User类,表中列属性=类变量
各种教程中花里胡哨的model讲解,让我对这个东西充满困惑,但拨云见雾,就是上面那句话。不要觉得model是个可怕的东西,它只是与数据库之前的一个映射文件。
由于第一阶段的目的是登入登出,最快捷的方法就是借用Django自带的user表,进一步可以使用大量好用的内置函数。
首先创建一个Django自带的User:终端下执行
python manage.py migrate
![189d6a3215ebefacbebaa2a2cb94a666.png](https://i-blog.csdnimg.cn/blog_migrate/1bac2de3a00a7ded92993ed03a0f2bdf.jpeg)
用Navicat打开db.sqlite3
,发现下面已经建好了这些表,其中auth_user就是Django自带的User,有很多已经存在的API可以直接调用。其他表暂时不用管。
![0a810da75742e6ee46b0316276eb6e7c.png](https://i-blog.csdnimg.cn/blog_migrate/6e2ad63b5a81e739c89e5605eba7f5a0.png)
可以看到,auth_user下有这些字段
![8a1a770cb720cfdec8e0d1b2b17cdb39.png](https://i-blog.csdnimg.cn/blog_migrate/9047c80cc8d3afa1c6d9e9825baa4f02.png)
但有很大的可能,auth_user并不能满足你的要求,比如学号、身份证号、职务等等
Django提供了扩展user的可能性,来左边跟我一起画条龙
![b05b24f128e2e3244e5bc39e4e426818.png](https://i-blog.csdnimg.cn/blog_migrate/1b83555a5b43a7ea250e8070bfe957c0.jpeg)
from django.contrib.auth.models import AbstractUser
import django
下面的User是我为教务管理系统设计的,不难看懂,不多解释。
class User(AbstractUser):
username = models.CharField(max_length=20, primary_key=True, db_index=True)
password = models.CharField(max_length=100, null=False)
name = models.CharField(max_length=50)
id_card = models.CharField(max_length=20)
sex = models.CharField(max_length=2)
school = models.CharField(max_length=20)
major = models.CharField(max_length=20)
sclass = models.CharField(max_length=20)
admin_data = models.DateField(blank=True, default=django.utils.timezone.now)
is_teacher = models.BooleanField(default=False)
def __str__(self):
return self.name
在setting.py下添加一行声明,也就是告诉项目“我不用你的user了,爸爸自己有”
AUTH_USER_MODEL = "usermng.User"
![07464ef523bdf644df33b2be151a1d28.png](https://i-blog.csdnimg.cn/blog_migrate/2923f5fdb49184da2fbe8093cae59cad.jpeg)
做完这一步,我们要更新项目数据库(建表)
终端先后输入
python manage.py makemigrations usermng
python manage.py migrate usermng
如果出现报错,可以参考下面的解决方案。(我也报错,真的解释不清)
报错django.db.migrations.exceptions.InconsistentMigrationHistory - WoLykos - 博客园www.cnblogs.com![21a0e1b31d77bbf5d217cc42fff31ed0.png](https://i-blog.csdnimg.cn/blog_migrate/8b2d1c80acedb107df65607f46dadf32.png)
不出意外,自定义的user表就出现了,里面会包含User自带属性+自定义属性
![1ed4a243c92e5d692e744c16e05369aa.png](https://i-blog.csdnimg.cn/blog_migrate/5d6c4a2030ed22ce3a4f61d60b10b0cd.png)
2. 登录
登录操作借助Django自带函数实现(除了登录,Django还提供了登出、登录状态判断、注册等内置函数,真香!)
为了方便后续测试,我们先创建一个超级管理员用户。在终端输入
python manage.py createsuperuser
![44875e91c0a48a533370e46f5d398253.png](https://i-blog.csdnimg.cn/blog_migrate/89fbfb155412bd8bea887b0a95dba302.jpeg)
从Navicat看一下,已经创建成功了
![a84f73a5b9f6e01dc0d9e172220a8e0e.png](https://i-blog.csdnimg.cn/blog_migrate/96a73628e85f356eabf2759a5c26f0de.png)
Django默认使用pbkdf2_sha256
的动态加密方式,因此数据库中密码为密文保存。下面,我们借助这个刚创建的用户,测试登录功能。
回到我们的菜鸡登录函数index(),导包
from django.contrib.auth import authenticate, login
authenticate用于认证用户名与密码,login执行登录功能
def index(request):
if request.method == "POST":
user = authenticate(username=request.POST.get("username"), password=request.POST.get("password"))
if user:
login(request, user)
return render(request, "welcome.html", {"username": request.POST.get("username")})
else:
return render(request, "index.html", {"error_message": "用户名或密码错误!"})
else:
return render(request, "index.html")
![3e82edf5f205c8fc82942c3c4841032e.png](https://i-blog.csdnimg.cn/blog_migrate/4f85b761231bee8275bfc60e23ef29fa.jpeg)
可以看到,通过认证的用户,跳转至welcome.html页面,而未通过验证的用户,将停留在原地,并弹出alert提示。前端welcome不动,index.html添加报错引导:
{% if error_message %}
<script type="text/javascript">
alert("{{ error_message }}");
window.location.href = "/usermng/index.html";
</script>
{% endif %}
![85cb5bfc0b99503321107ffaed81587f.png](https://i-blog.csdnimg.cn/blog_migrate/5ac93be08fdceaeaababf770babd2801.jpeg)
我个人比较倾向于error_message
走天下 ,这样只用修改后端不同的报错消息,前端无脑显示即可。你也可以通过return不同的state,在前端展示更为复杂的功能。
3. 测试
首先正常登录
![302db03f3d4ff65e3b274f2224371fd2.png](https://i-blog.csdnimg.cn/blog_migrate/bc57dc638f9a4c8d46c79ff6a78ae5aa.png)
![e791e71af8d4b89298ade0f20d82b82c.png](https://i-blog.csdnimg.cn/blog_migrate/8518aa6c9cc1f7aa2490b12cea6a19a6.png)
再试试输错的情况
![cab086d6d47d854b5bca4c4012c2739b.png](https://i-blog.csdnimg.cn/blog_migrate/210244b262b7f6c8a23292cff2abde6e.png)
![da8b28f96b3121d727301ccb0a16012c.png](https://i-blog.csdnimg.cn/blog_migrate/5a758aa4dbae2f57367d904f29f5ddde.png)
测试通过
4. 登出
首先,在welcome.html添加一个登出按钮
<div>
<a href="{% url 'usermng:user_logout' %}"> 退出登录 </a>
</div>
![d14db56bebada94acc90ed28a6c206d8.png](https://i-blog.csdnimg.cn/blog_migrate/03faf63aba39c875ab2fb8ab840d66f6.jpeg)
再在urls.py中配置这个超链接的映射。
path('logout/', views.user_logout, name='user_logout'),
![c3ed02810af256ed22d3dde423d569f5.png](https://i-blog.csdnimg.cn/blog_migrate/65deeee4e50bbd1cb144148774984188.png)
views.py下配置登出函数,记得前面引入一下登出函数from django.contrib.auth import authenticate, login, logout
def user_logout(request):
logout(request)
return render(request, "index.html")
测试看看
![c8208b4121bd66d6826b7684a78467cf.png](https://i-blog.csdnimg.cn/blog_migrate/049a07c2fe658a4c19986b4b0a52eba4.png)
![93605c7367872e76a14bed12c7f03bf4.png](https://i-blog.csdnimg.cn/blog_migrate/490f2c724ff3b4619fa47a485d5adbc6.png)
登出成功
5. 访客阻挡
直接访问welcome.html地址,发现,不经登录也能访问
![d6228399e04095b1503244099a708adc.png](https://i-blog.csdnimg.cn/blog_migrate/bd615654a688974c16f7c342466ab26b.png)
那这搞了半天的登录,没屁用啊好像。一拍脑壳,咱得搞个访客阻挡!
{% if not user.is_authenticated %}
<script type="text/javascript">
alert("请登录!");
window.location.href = "/usermng/index.html";
</script>
{% endif %}
![5baae08aa36b01f7e332346783c67977.png](https://i-blog.csdnimg.cn/blog_migrate/226bf26495bf663b228461e324143319.jpeg)
访问看看,成功拦截!
![ebfaed24cf98bd2d056360158244a040.png](https://i-blog.csdnimg.cn/blog_migrate/d1f34fae35ef13c750927820afa9b8b2.png)
这一节涉及到不少内容,但都点到为止。下一节会更加深入讨论数据库与后端的交互,增删查改,欢迎移步。
koko可可:Django从入门到大作业:5-ORM操作zhuanlan.zhihu.com