ORM练习(利用数据查询/增加/修改做登录/注册/用户查询页面)
ORM命令大全
# 创建主键 名为id字段
id = models.AutoField(primary_key=True,verbose_name='主键')
'''
primary_key=True 是自增的意思
verbose_name='主键' 是对字段的解释、注释,可以不加
'''
# 创建char类型,名为username的字段
username = models.CharField(max_length=32)
'''max_length=32 是范围限制,表示最多32位'''
# 创建int类型,名为password的字段
password = models.IntegerField()
ORM命令参数解释
hobby = models.CharField(max_length=32,verbose_name='兴趣爱好',default='学习')
'''
max_length=32 是范围限制,表示最多32位,字符串类型必须设置的参数
verbose_name 是该字段的解释,所有字段都应该有的
default='学习' 是默认值的意思
'''
一、ORM练习之数据查询
之前我们学会request对象,后端可以获取前端提交的数据,现在我们又学会了ORM操作数据库的方法。那么我们就来实现下面的需求,
用户在浏览器登录账号,点击登录提交。
后端拿到用户提交的数据,然后去数据库和数据对比。
如果对比一致,就打印 登录成功,否则失败
def login(request):
user = request.POST.get('username')
pwd = request.POST.get('password')
from app01 import models
res = models.User.objects.filter(username=user) # 查询数据库
obj1 = res[0]
print(obj1) # User object
print(obj1.username) # poco
print(obj1.password) # 123
return render(request, 'login.html')
'''【分析】
user = request.POST.get('username')
pwd = request.POST.get('password')
上面这两段代码拿的是前端用户输入的 用户名和密码
res = models.User.objects.filter(username=user)
这段代码拿的是数据库里的一个对象,它可以调用方法
obj1.username
obj1.password
这两段代码是真正的拿到是数据库里的用户和密码
'''
1、用户登录(后端视图层逻辑代码)
def login(request):
# 如果用户提交POST请求,就运行下列代码
if request.method == 'POST':
# 拿到用户提交的数据
user = request.POST.get('username')
pwd = request.POST.get('password')
# 导入models模型层
from app01 import models
# 查询数据库里的数据
res = models.User.objects.filter(username=user).first()
obj1 = res
# 前端用户名和数据库的用户名进行比对,然后根据不同的判断结果显示不同内容
if user == obj1.username:
if pwd == obj1.password:
return HttpResponse('登录成功')
else:
return HttpResponse('密码错误')
else:
return HttpResponse('用户名不存在')
# 用户提交GET请求运行,这行代码
return render(request, 'login.html')
1-1、遇到的错误
'''
问题1:明明前端输入的密码和数据库密码一样,但验证密码时总是不对
解决方法:前端拿到的数据都是str类型,我把密码字段设置成了int类型,所以我把字段改成了数据库的char类型。这里也可以把前端拿到的数据转换成int类型
'''
#####################################################
'''
问题2:在测试时,我输入一个数据库不存在的用户名时,总是报错,
AttributeError: 'NoneType' object has no attribute 'username'
按照我上面写的代码来说,应该是返回一个用户名不存在的页面
解决方法:按理来说filter查询即使查不到也不会报错的。。。不知道为什么
只好用一个异常捕获的代码解决了。。。。
def login(request):
try:
if request.method == 'POST':
user = request.POST.get('username')
pwd = request.POST.get('password')
from app01 import models
res = models.User.objects.filter(username=user).first()
obj1 = res
if user == obj1.username:
if pwd == obj1.password:
return HttpResponse('登录成功')
else:
return HttpResponse('密码错误')
except AttributeError as e:
return HttpResponse('用户名不存在')
return render(request, 'login.html')
'''
2、用户注册
def reg(request):
if request.method == 'POST':
user = request.POST.get('username')
pwd = request.POST.get('password')
res = models.User.objects.create(username=user, password=pwd)
return render(request,'reg.html')
3、用户数据展示以及编辑、删除
首先是前端页面,用于展示数据和提供编辑、删除按钮
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<link rel="stylesheet" href="{% static '/css/bootstrap.min.css' %}">
</head>
<body>
<h1 class="text-center">数据展示</h1>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>username</th>
<th>password</th>
<th>action</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_queryset %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td>
<a href="" class="btn btn-primary btn-xs">编辑</a>
<a href="" class="btn btn-danger btn-xs">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
然后就是后端视图层的逻辑代码,用locals()把内容全部显示到前端去
# 数据展示
def userlist(request):
user_queryset = models.User.objects.all()
return render(request,'userlist.html',locals())
好,数据的查询我们已经做到了,现在我们该做编辑、删除功能了,HTML代码里不是有编辑和删除的按钮吗,我们在后端开放编辑和删除的接口就好了,接下来我们拿删除做一个举例
# 我们先去路由层开一个接口
url(r'^edit_user/', views.edit_user),
# 然后去视图层写删除的逻辑,这里先简单的演示一下
def edit_user(request):
return HttpResponse('编辑用户')
# 修改userlist的HTML文件 编辑按钮
<a href="/edit_user/" class="btn btn-primary btn-xs">编辑</a>
# 然后再去创建一个edit_user的HTML文件,点击编辑按钮就可以跳转到这个页面修改数据,可以拿之前用户注册的页面改一改
现在又有一个问题,前端如果点击 编辑和删除的按钮,后端如何知道前端点击的是哪一条数据呢,如果不知道具体是哪一条数据,我们就无法进行编辑和删除了。如何解决?请看下面
'''
如何告诉后端,用户想要编辑的是哪条数据?
我们知道【问号(?)】后面的参数不会参与路由匹配,所以利用url问号后面携带参数的方式,
将编辑按钮所在的那一行数据的主键值发送给后端
'''
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td>
<a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a>
<a href="" class="btn btn-danger btn-xs">删除</a>
</td>
'''能够理解上面那行代码吗?,?user_id={{ user_obj.id }}这行代码我们就能获取到用户的主键id
比如说前端点击了第一条数据的编辑按钮,它的url就是这样的,类似于get请求'''
http://127.0.0.1:8000/edit_user/?user_id=1
# 所以我们后端就可以用request.GET.get('user_id')的方式获取到前端点击的具体数据了
def edit_user(request):
# 获取 url问号后面的参数
edit_id = request.GET.get('user_id')
# 查询当前用户想要编辑的数据对象
edit_obj = models.User.objects.filter(id=edit_id).first()
# 将对象数据展示到页面上
return render(request, 'edit_user.html',locals())
视图层edit_user函数完整的逻辑
def edit_user(request):
# 获取 url问号后面的参数
edit_id = request.GET.get('user_id')
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 修改数据库对应的数据内容
models.User.objects.filter(id=edit_id).update(username=username, password=password)
# 数据修改完毕跳转回 原页面
return redirect('/userlist/')
# 查询当前用户想要编辑的数据对象
edit_obj = models.User.objects.filter(id=edit_id).first()
# 将对象数据展示到页面上
return render(request, 'edit_user.html', locals())
编辑我们就已经完成了,接下来就是删除功能,学会了编辑,删除就很简单了。。。和编辑的操作大同小异。。
# 我们先去路由层开一个接口
url(r'^del_user/', views.del_user),
# 然后去视图层写删除的逻辑,这里先简单的演示一下
def del_user(request):
pass
# 修改userlist的HTML文件 删除按钮
<a href="/del_user/?user_id={{ user_obj.id }}" class="btn btn-danger btn-xs">删除</a>
删除完成(删除按理来说应该增加一个二次确认,目前我们就先不实现这个需求了)
def del_user(request):
# 获取url问号后面的参数
del_id = request.GET.get('user_id')
# 删除按钮
models.User.objects.filter(id=del_id).delete()
# 删除完成跳转回到查询页面
return redirect('/userlist/')

浙公网安备 33010602011771号