django初级应用
一.实现在浏览器中输入内容,跳转拓展页面继续输入下一个内容, 然后提交到数据库,再从数据库中获得数据显示在浏览器中
1)配置:
添加app='stu',修改路由
(?P<stu_id>):
工程路由,添加路由stu:
(?P<name>...) 子串匹配到的内容将可以用命名的name来提取url中的值。组的name必须是有效的python标识符,而且在本表达式内不重名。
app路由,添加路由addstu:
2)models.py创建数据表
db_table 用来给表命名
from django.db import models
# Create your models here.
class Student(models.Model):
s_name = models.CharField(max_length=10)
s_tel = models.CharField(max_length=11)
class Meta:
db_table = 'day51_student'
class StudentInfo(models.Model):
i_addr = models.CharField(max_length=30)
s = models.OneToOneField(Student)
class Meta:
db_table = 'day51_stuedentinfo'
3) templates书写addStu.html
实现浏览器的输入,提交
form表单中写入路径action, 提交方法method;提交按钮的type类型为submit
<form action="" method="POST">
<table>
<tr>
<th>姓名</th>
<th>电话</th>
</tr>
<tr>
<td>
<input type="text" name="name">
</td>
<td>
<input type="text" name="tel">
</td>
</tr>
<tr>
<td>
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
4)views.py写addStu方法
request.method :请求的方法;
GET:获得请求, POST:提交请求敲黑板: reverse函数在pycharm中不能直接使用alt + enter导入,需要手动导入:from django.core.urlresolvers import reverse,用来实现跳转到指定页面
render与redict区别:
HttpResponseRediect函数:return rediect('/login.html/'):执行的的是url里面的函数,相当于又一次调用新的函数,/login.html/函数里面的所有代码都会执行,并且路径也会改变,用户再次刷新的时候不会改变
render:return render(request,'addStu.html'):只是跳到login.html这个页面上去,没有别的任何操作,和url里的调用都不执行,并且路径还是原来的路径,
当用户再次刷新时,会会重新回到原来路径下的页面
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.core.urlresolvers import reverse
# Create your views here.
from stu.models import Student, StudentInfo
def addStu(request):
if request.method == 'GET':
return render(request, 'addStu.html') #跳转到addStu.html页面中
if request.method == 'POST':
# 跳转到学习详情页面
name = request.POST.get('name')#获得POST请求携带的内容,数据存在form date中
tel = request.POST.get('tel')
# 在数据库中创建相应数据
stu = Student.objects.create(
s_name=name,
s_tel=tel
)
# 跳转到下一个页面
return HttpResponseRedirect(
# 路径别名's:red', 传入可变的参数字典 kwargs = {'stu_id':stu.id}
# 因为路径是可变的,所以需要使用别名
# stu.id 为数据中创建数据的id
reverse('s:red', kwargs={'stu_id': stu.id})
)
5)学生拓展表studentinfo,书写addStudentInfo方法
# 传入网址上提取到的url(stu_id)变量
def addStuInfo(request, stu_id):
if request.method == 'GET':
# GET请求,跳转到指定的html页面
return render(request, 'addStuInfo.html', {'stu_id': stu_id})
if request.method == 'POST':
stu_id = request.POST.get('stu_id')
addr = request.POST.get('addr')
StudentInfo.objects.create(i_addr=addr, s_id=stu_id)
# 提交完毕后返回首页
return HttpResponseRedirect('/stu/index/')
6)书写studentinfo.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="POST">
<input type="hidden" value="{{ stu_id }}" name="stu_id">
地址:<input type="text" name="addr">
<input type="submit" value="提交">
</form>
</body>
</html>
7)定义首页index.html
</head>
<body>
{% for stuinfo in stuinfos %}
{# 第一次首页的时候, 数据库中没有数据, 添加完毕后, 数据中则有数据,从数据库中取出相应的数据#}
姓名: {{ stuinfo.s.s_name }}
电话: {{ stuinfo.s.s_tel }}
地址: {{ stuinfo.i_addr }}
{% endfor %}
<h4>--------------------------------------</h4>
<a href="{% url 's:add' %}">添加学生</a>
</body>
</html>
二. 实现浏览器登入登出,cookie的使用
登入:查询数据库有没有改用户,没有的话就跳转到注册regist页面,有就进入login页面, 再次刷新的时候需要重新登录
登出: 注册掉数据库相关数据
1)准备:采用第一个项目里的template数据,新建app:uauth
工程urls:
python url(r'^uauth/', include('uauth.urls'))
app urls:
2)创建对应的数据库表
ticket 随浏览器走
from django.db import models
# Create your models here.
class Users(models.Model):
u_name = models.CharField(max_length=10)
u_password = models.CharField(max_length=255)
u_ticket = models.CharField(max_length=30, null=True)
class Meta:
db_table = 'day51_user'
3)书写regist, login , logout相应方法
- regist
密码加密:make_password()
密码解密:check_password()
from django.contrib.auth.hashers import make_password,check_password
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.core.urlresolvers import reverse
# Create your views here.
from uauth.models import Users
def regist(request):
if request.method == 'GET':
return render(request, 'register.html')
if request.method == 'POST':
# 注册
name = request.POST.get('name')
password = request.POST.get('password')
password = make_password(password)
Users.objects.create(u_name=name,u_password=password)
return HttpResponseRedirect('/uauth/login/')
- login
拓展 Httpresponse.set_cookie
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
- 设置一个Cookie。参数与Python 标准库中的 Morsel Cookie 对象相同。
key:键名,字符串形式。 - value:对应的值,字符串形式。
- max_age:cookie 过期的相对时间,单位是秒。如果为None,则当浏览器关闭的时候过期。如果设置了 max_age 而没有设置 expires,则 expires 将根据 max_age 的值计算出来。
- expires:设置 cookie 过期的绝对时间。应该是一个 UTC "Wdy, DD-Mon-YY HH:MM:SS GMT" 格式的字符串,或者一个 datetime.datetime 对象。如果 expires 是一个datetime 对象,则 max_age 会通过计算得到。
- path:一个字符串,表示客户端回送 cookie 的路径,如果为‘/’,则表示该域名下的所以路径都将回送 cookie,如果是‘/blog/’;则在访问‘/blog/abc’或者‘/blog/def’等,所有包含该前缀的路径时,客户端都会回送 cookie。
- domain:cookie有效的域。例如,其值为‘.scolia.com’时,那么在访问 www.scolia.com 或者 test.scolia.com 之类的时,都会回送 cookie ,当然通常会和 path 配合在一起使用。根据 HTTP 协议的要求,这个值必要要两到三个句点,从而防止出现 ‘.com’、‘.edu’、‘va.us’等形式的域名。当域为高层域时,只要两个句点就可以了,而高层域包括:.com、.edu、.net、.org、.gov、.mil、.int、.biz、.info、.name、 .museum、.coop、.aero、和.pro。其他的域则需要至少三个。
- secure:当其为 True 时,表示只要在 https 连接的情况下才会回送cookie
httponly:当其为 True 时,JavaScript 等就不能访问对应的cookie了。当然这个标记并不是cookie标准中的,但目前市面上常用的浏览器都支持。灵活使用可以提供数据的安全性。
注意: - RFC 2109 和RFC 6265 都声明客户端至少应该支持 4096 个字节的Cookie。对于许多浏览器,这也是最大的大小。如果视图存储大于 4096 个字节的 Cookie,Django 不会引发异常,但是浏览器将不能正确设置 Cookie。
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
if request.method == 'POST':
# 如果登录成功,绑定参数到cookie中,set_cookie
name = request.POST.get('name')
password = request.POST.get('password')
if Users.objects.filter(u_name=name).exists():
user = Users.objects.get(u_name=name)
if check_password(password, user.u_password):
ticket = 'agdoajbfjad'
# 绑定令牌到cookie里面
response = HttpResponse()
#response返回的是<HttpResponse status_code=200, "text/html; charset=utf-8">
response.set_cookie('ticket', ticket)
# 存在服务端
user.u_ticket = ticket
user.save()
return response
else:
return HttpResponse('用户密码错误')
else:
return HttpResponse('用户不存在')
- logout
删除cookie
HttpResponse.delete_cookie(key, path='/', domain=None)
cookie中删除指定的 key 及其对应的 value。如果 key 不存在则什么也不发生,也就是不会引发异常。
由于 Cookie 的工作方式,path 和 domain 应该与 set_cookie() 中使用的值相同 —— 否则 Cookie 不会删掉。
def logout(request):
if request.method == 'GET':
response = HttpResponse()
response.delete_cookie('ticket')
return HttpResponseRedirect('/uauth/login/')
4)书写相应的html文件
- register注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<form action="" method="POST">
注册姓名:<input type="text" name="name">
注册密码:<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
- login 登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<form action="" method="POST">
登录姓名:<input type="text" name="name">
登录密码:<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
5)书写首页index.html
实现登陆后跳转到指定页面,没登录跳转到登录页面
def index(request):
if request.method == 'GET':
# 获取所有学生信息
ticket = request.COOKIES.get('ticket')
if not ticket:
return HttpResponseRedirect('/uauth/login/')
if Users.objects.filter(u_ticket=ticket).exists():
stuinfos = StudentInfo.objects.all()
return render(request, 'index.html', {'stuinfos': stuinfos})
else:
return HttpResponseRedirect('/uauth/login/')
三.零碎的小规模验证应用
1.404 和 500 异常处理
404:主要是代码的错误,导致不能正常打开页面
500:主要是url输入的错误,导致服务出现问题,不能正常打开页面
1)在对应的app中编写错误处理方法
#404
def page_not_found(request):
return render(request, '404.html')
#500
def server_error(request):
return render(request, '500.html')
2)书写相应的html文件
404
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>这里是400,400</h1>
</body>
</html>
500
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>500错误页面</title>
</head>
<body>
<h1>这里是500, 500</h1>
</body>
</html>
3)在工程目录下urls导入写入的模块,赋值到相应的错误处理模块上
from stu.views import page_not_found, server_error
handler404 = page_not_found
handler500 = server_error
2.挖坑与填坑
在html文件中,实现内容的重复利用
- 挖坑:base.html (标题title ---- 内容body)
方法:{% block title %} {% endblock %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %} {% endblock %}
</title>
</head>
<body>
{% block contains %} {% endblock %}
</body>
</html>
- 填坑 grade.html
>引用的是base.html中的内容,将grade填掉的内容加入到base中挖掉的内容中
{% extends 'base.html' %}
{% block title %}
班级列表
{% endblock %}
{% block contains %}
{% for g in gs %}
班级ID:{{ g.id }}
<a href="/s/allstu/{{ g.id }}">
{# <a href="{% url 's:alls' g.id %} ">#}
班级名称:{{ g.g_name }}
</a>
{% endfor %}
{% endblock %}
3.数据库表的更新与删除(update, delete)
- 更新
方法:1-需要手动保存
def upStu(request):
stu_id = request.GET.get('stu_id')
stu = Student.objects.get(id=stu_id)
stu.s_name = '修改的名字'
stu.save()
方法2:自动保存
def upStu(request):
stu_id = request.GET.get('stu_id')
Student.objects.filter(id=stu_id).update(s_name='黄蓉')
return HttpResponseRedirect('/g/allgrade/')
- 删除
def delStu(request):
stu_id = request.GET.get('stu_id')
Student.objects.filter(id=stu_id).delete()
return HttpResponseRedirect('/g/allgrade/')
4.关联关系
OnetoOneField:一对一关系
ForeignKey: 一对多关系
ManytoMany: 多对多关系