5. 视图和模型结合使用
5.1 设计展示用户操作页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="sucess.html">
输入用户名:<input type="text" name="name" id="name"><br>
年龄:<input type="text" name="age" id="age"><br>
电话:<input type="text" name="phone" id="phone"><br>
<button type="submit">提交</button>
</form>
</body>
</html>
5.2 设置页面对应的路径,当用户请求的时候,展示
from django.http import HttpResponse
def show(request):
return render(request,'show.html')
注意点:
- 必须传入一个参数
- 返回一个
HttpResponse
对象
5.3 HTTP请求对象
<WSGIRequest: GET '/showregister'>
- 这是一个HTTP请求对象
- 这个请求对象里面封装的是请求信息,包括请求的方式,数据
requeset
相关属性:
http://127.0.0.1:8000/book/bookinfo10/
描述 | |
---|---|
path | /book/bookinfo10/ |
5.3.1 request.body
当废表单数据,request.body
来获取到请求体数据,但是,body获取的数据是bytes类型
一般情况下是json
5.3.2 request.GET
获取到都是类字典类型-
5.3.3 request.POST
获取到都是类字典类型
5.3.4 request.META 获取请求头数据
print(request.META)
print(request.META['HTTP_USER_AGENT'])
#Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
5.4 HTTPResponse 对象
5.4.1 render 函数的具体使用
def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
注意点:
render
函数适用范围:有网页,有填充网页的数据render
函数的第一个参数:当前路径的请求对象context
:填充网页的数据,格式为字典类型
5.5 路径传参
在urls.py
中添加
url(r'^(\d+)$',views.bookinfo10),
在view.py
中添加
def bookinfo10(request,param=None):
print(param)
return HttpResponse('测试试试')
绑定参数,关键字传参的问题
url(r'^(?P<param>\d+)/(?P<param2>\w+)$',views.bookinfo10),
在view.py
中添加
def bookinfo10(request,param2=None,param=None):
print(request.path)
print(param)
print(param2)
return HttpResponse('测试试试')
5.6 例子
实现:页面出现所有的书籍,在每本书籍的后面两个按钮,一个按钮展开详情页,一个按钮可以删除这本书
view.py
文件
def showbookinfo(request):
# todo 1. 从数据库讲所有的书籍加载出来
book_obj_list = BookInfo.objects.all().filter(is_delete=False)
# todo 1.1 将数据拼接上下文
context = {'data':book_obj_list}
# todo 2. 将数据传递给前端
return render(request,'books.html',context)
# return JsonResponse({"data":"ok"},safe=False)
def deletebook(request,book_id=None):
# 物理删除 1
# book = BookInfo.objects.get(id=book_id)
# book.delete()
# 物理删除 1
# book = BookInfo.objects.filter(id=book_id).delete()
# 逻辑删除
book = BookInfo.objects.get(id=book_id)
book.is_delete=1
book.save()
book_obj_list = BookInfo.objects.all().filter(is_delete=False)
context = {'data': book_obj_list}
# return HttpResponse('okg')
return render(request, 'books.html',context)
def showbook(request,book_id=None):
book = BookInfo.objects.get(id=book_id)
book_obj_list = BookInfo.objects.all().filter(is_delete=False)
context = {'data': book_obj_list}
return render(request,'books.html',context)
urls.py
文件
url(r'^showbookinfo',views.showbookinfo),
url(r'^deletebook/(\d+)$',views.deletebook),
url(r'^showbook/(\d+)$',views.showbook),
books.html
页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var temp='';
function showAction(id,xxx,yyy){
if(temp===""){
document.getElementById(id).innerHTML=xxx;
temp = 'show';
}
else {
document.getElementById(id).innerHTML=yyy;
temp = '';
}
}
</script>
</head>
<body>
<ul>
{% for obj in data %}
<li><span id={{ obj.id }}>{{ obj }}</span><a href="/book/deletebook/{{ obj.id }}"><button>delete</button></a><button onclick="showAction({{ obj.id }},'{{ obj.bookname }}--{{ obj.publictime }}--{{ obj.count }}--{{ obj.seltcount }}','{{ obj }}')">show</button></li>
{% endfor %}
</ul>
</body>
</html>
5.7 前后端分离
from django.http import HttpResponse,JsonResponse
def showbookinfo(request):
return JsonResponse({"data":"ok"},safe=False)
5.7 关于浏览器与服务器之间的状态保持
5.7.1 cookie
浏览器与服务器之间是无状态的
session:存在服务器一端
cookie:一一对应
特点:
- 键值结构
- cookie是基于域名安全的,不同域名之间cookie是不可以进行相互访问的
- 当浏览器请求某一网站,会将于当前网站所有的cookie提交给服务器
- cookie数据不允许存储敏感信息,密码,支付码密码
5.7.2 cookie的设置
创建cookie:cookie是服务器设置,所以返回一个response
def set_cookie(self, key, value='', max_age=None, expires=None, path='/',domain=None, secure=False, httponly=False):
"""
Sets a cookie.
``expires`` can be:
- a string in the correct format,
- a naive ``datetime.datetime`` object in UTC,
- an aware ``datetime.datetime`` object in any time zone.
If it is a ``datetime.datetime`` object then ``max_age`` will be calculated.
"""
def set_cookies(request):
response = HttpResponse('设置cookie')
# def set_cookie(self, key, value='', max_age=None, max_age的单位是s,如果是临时cookie,设置为None
response.set_cookie('name1','python')
response.set_cookie('name2','django',max_age=3600)
return response
获取cookie:浏览器存在浏览器,获取是通过request
def get_cookies(request):
print('99999999999999999999999999999999999')
print(request.COOKIES.get('name1'))
print(request.COOKIES.get('name2'))
return HttpResponse('获取cookies')
删除cookie:cookie是服务器设置,需要返回response
def delete_cookies(request):
response = HttpResponse('删除cookies')
response.delete_cookie('name1')
return response
总结:Cookie虽然存储在浏览器一端,但是,它是在服务器一端进行设置的,
5.7.3 session
-
需要使用数据库存储session,安装应用
setting.py
中INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', # django中session是默认存储在我们的数据库中的,一旦存在数据库中,就需要在INSTALLED_APPS中进行注册 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 定义子应用 #'user' 'user.apps.UserConfig', 'book.apps.BookConfig', ]
-
在数据库中
mysql> show tables; +----------------------------+ | Tables_in_pai0805 | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | bookinfo | | django_admin_log | | django_content_type | | django_migrations | | django_session | | personinfo | | user_userinfo | +----------------------------+
mysql> desc django_session; +--------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+-------------+------+-----+---------+-------+ | session_key | varchar(40) | NO | PRI | NULL | | | session_data | longtext | NO | | NULL | | | expire_date | datetime(6) | NO | MUL | NULL | | +--------------+-------------+------+-----+---------+-------+
注意:在Django项目中,session的引擎没有设置,则是默认的存储方式
5.7.4 session的安装配置
-
第一种方式:存储在本地缓存
# 设置session存储在本地缓存 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 缺点:如果丢失不能找回 # 优点:比数据库读写快
-
第二种方式:混合存储
# 混合存储:内存和数据库混合存储 SESSION_ENGINE = 'django.contrib.sessions.backends.cache_db' # 优先从本机内存中,存取,如果没有,从数据库存取
-
第三种方式:存在redis非关系性数据库中
# 存在redis非关系性数据库中 # 1. 安装第三方扩展 # pip install django-redis # 2. 配置redis CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "123", } } } SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'default' # SESSION_COOKIE_AGE = 60 * 5 #设置5分钟过期,不设置用系统默认 # 3. 绑定ip地址 # sudo vi/etc/redis/redis.conf # 4. 重启redis服务 # sudo service redis-server restart
5.7.5 session的设置
设置session
def set_session(request):
request.session['session1'] = 'hello'
return HttpResponse('设置session')
获取session
def get_session(request):
print(request.session.get('session1'))
# 清空所有的session值
request.session.clear()
# 删除 整条数据
request.session.flush()
# 删除 指定的数据
del request.seseion['sess1']
return HttpResponse('得到session')
5.8 中间件的使用
5.8.1 创建一个中间件
user
文件夹中创建middleware.py
文件
def my_middle(get_request):
print('init开始被调用')
def middileware(request):
print('before requst被调用')
reponse = get_request(request)
print('after reponse被调用')
return reponse
return middileware
5.8.2 注册进settings文件中
# 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 默认开始csrf的校验
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'user.middleware.my_middle', # 注册中间件
]
5.8.3 多个中间件的顺序
# 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 默认开始csrf的校验
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'user.middleware.my_middle', # 注册中间件
]
在请求视图被处理之前,中间件的顺序自上而下
在请求视图被处理之后,中间件的顺序自下而上