python&&Django框架&&学习笔记三

分页的实现

配置web models.py

from django.db import models

# Create your models here.
class Host(models.Model):
    HostName = models.CharField(max_length=256)
    ip = models.GenericIPAddressField()

配置web urls.py

"""LearnDjangoThree URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from web import views

urlpatterns = [
    path('index/<int:page>', views.index),
]

配置web views.py

from django.shortcuts import render
from django.shortcuts import render_to_response
from django.shortcuts import HttpResponse
from web import models
from web import html_helper
#引用mark_safe模块,令html标签等代码内容不干扰正常python逻辑代码
from django.utils.safestring import mark_safe
# Create your views here.
def index(request,page):
    #捕捉page的类型,确保page总是为正整形
    try:
        page = int(page)
    except Exception:
        page = 1
    count = models.Host.objects.all().count()
    pageObj = html_helper.PageInfo(page,count,)
    rcvData = models.Host.objects.all()[pageObj.start:pageObj.end]
    rcvCount = models.Host.objects.all()[pageObj.start:pageObj.end].count()
    pageEle = html_helper.Pager(page,pageObj.all_page_count)
    ret = {'status':'','data':rcvData,'rcvCount':rcvCount,'page':page,'pageEle':pageEle}
    return render_to_response('web/index.html',ret)

配置web html_helper.py

#!/usr/bin/env python
#coding:utf-8
from django.utils.safestring import mark_safe
#文件html_helper.py:用于存放操控html页面的常用函数。
#定义类PageInfo,完成分页数据(页数)的计算
class PageInfo(object):
    '''
    current_page:当前页
    all_count:总数据条数
    per_item:每页条数(默认是5)
    start:从数据库取范围数据的起始位置
    end:从数据库取范围数据的结束位置
    all_page_count:全部数据库数据总共可分为多少个分页
    '''
    def __init__(self,current_page,all_count,per_item=5):
        self.CurrentPage = current_page
        self.AllCount = all_count
        self.PerItem = per_item
    #使用装饰器"@property",调用该函数时可省略函数名后面的"()".即"pageObj.start()">"pageObj.start"
    @property
    def start(self):
        return (self.CurrentPage-1)*self.PerItem
    @property
    def end(self):
        return self.CurrentPage*self.PerItem
    @property
    def all_page_count(self):
        temp = divmod(self.AllCount, self.PerItem)
        if temp[1] == 0:
            all_page_count = temp[0]
        else:
            all_page_count = temp[0] + 1
        return all_page_count


#定义函数Pager.:生成首页、上一个、123、下一页、尾页的HTML
def Pager(page,all_page_count):
    '''
    page:当前是第几个分页
    all_page_count:当前一共有多少分页
    '''
    #定义列表page_html:存放html页面的元素标签
    page_html = []
    #定义首页
    first_html = "<a href='/web/index/%d'>首页</a>" %(1,)
    page_html.append(first_html)
    #定义上一页
    if page <= 1:
        #如果当前页小于等于1,此时点上一页则不进行任何操作
        prv_html = "<a href='#'>上一页</a>"
    else:
        prv_html = "<a href='/web/index/%d'>上一页</a>" %(page-1,) 
    page_html.append(prv_html)
    #定义分页1 分页2 分页3
    #定义分页段首分页
    begin = 0
    #定义分页段末分页
    end = 0
    #定义分页段长度为5
    #定义,默认html仅显示5个分页标签
    if all_page_count < 5:
         begin = 0
         end = all_page_count
    else:
        if page < 3:
            begin = 0
            end = page + 2
        else:
            begin = page-3
            if page + 2 < all_page_count:
                end = page + 2
            else:
                end = all_page_count
            
    for i in range(begin,end):
        if page == i+1:
            a_html = "<a href='/web/index/%d' class='selected' >%d</a>" %(i+1,i+1)
        else:
            a_html = "<a href='/web/index/%d'>%d</a>" %(i+1,i+1)
        page_html.append(a_html)
    #定义下一页    
    if page >= all_page_count:
        next_html = "<a href='#'>下一页</a>" 
    else:
        next_html = "<a href='/web/index/%d'>下一页</a>" %(page+1,)
    page_html.append(next_html)
    #定义尾页
    last_html = "<a href='/web/index/%d'>尾页</a>" %(all_page_count,)
    page_html.append(last_html)
    #整合列表page_html并与返回
    #使用mark_safe:返回有效的html元素标签pageEle。不使用mark_safe:在html页面输出代码段
    #使用join:将一个个的html元素标签用空格连接成一个大的字符串
    pageEle =mark_safe("".join(page_html))
    return pageEle

配置templates web index.html

<!doctype html>
<html>
    <head>
	    <!--对页面编码进行设置-->
	    <meta http-equiv="content-type" content="text/html;charset=utf-8">
		<!--兼容IE6浏览器-->
		<meta http-equiv="X-UA-Compatible" content="IE=Edge">
		<title>demo 10</title>
		<style>
			.hide{
			    display:none;
			}
			.clearfix:after{
			    content:".";
				display:block;
				height:0;
				clear:both;
				visibility:hidden;
			}
			body
			{
			    font-size:.85em;
				font-family:"Trebuchet MS",Verdana,Helvetica;
				color:#232323;
				background-color:#fff;
			}
			#Pageing A{
			    background-color:#008844;
			    border:1px solid White;
				text-decoration:none;color:White;
				padding: .1em .6em .2em .6em;
			}
			#Pageing A.selected{
			    background-color:#AA7700;
			}
		</style>

	</head>
	<body>
	    <h1>主机信息</h1>
		<table border="1">
	    {% for item in data %}
		    <tr>
			    <td>{{item.HostName}}</td>
			    <td>{{item.ip}}</td>
			</tr>
		{% endfor %}
		</table>
		<div>共计{{rcvCount}}条</div>
		<div id="Pageing" >{{pageEle}}</div>

		<!--引入jQuery文件-->
	    <script src="jquery-1.11.0.min.js"></script>
	    <script type="text/javascript">

		</script>
	</body>
</html>

Cookie与Session

关于Cookie

获取cookie:
request.COOKIES[key]
设置cookie:
response.set_cookie(key,value)
由于cookie保存在客户端的电脑上,所以,jquery也可以操作cookie

Cookie使用示例

cookie示例框架

在这里插入图片描述

配置web urls.py文件
from django.contrib import admin
from django.urls import path
from web import views
urlpatterns = [
    path('index/<int:page>', views.index),
]
配置web index.htm文件,在浏览器本地存放cookie数据
<!doctype html>
<html>
    <head>
	    <!--对页面编码进行设置-->
	    <meta http-equiv="content-type" content="text/html;charset=utf-8">
		<!--兼容IE6浏览器-->
		<meta http-equiv="X-UA-Compatible" content="IE=Edge">
		<title>demo 10</title>
		<style>
			.hide{
			    display:none;
			}
			.clearfix:after{
			    content:".";
				display:block;
				height:0;
				clear:both;
				visibility:hidden;
			}
			body
			{
			    font-size:.85em;
				font-family:"Trebuchet MS",Verdana,Helvetica;
				color:#232323;
				background-color:#fff;
			}
			#Pageing A{
			    background-color:#008844;
			    border:1px solid White;
				text-decoration:none;color:White;
				padding: .1em .6em .2em .6em;
			}
			#Pageing A.selected{
			    background-color:#AA7700;
			}
		</style>

	</head>
	<body>
	    <h1>主机信息</h1>
		<table border="1">
	    {% for item in data %}
		    <tr>
			    <td>{{item.HostName}}</td>
			    <td>{{item.ip}}</td>
			</tr>
		{% endfor %}
		</table>
		<div>共计{{rcvCount}}条</div>
		<div id="Pageing" >{{pageEle}}</div>
		<!--cookie使用示例-->
		<div>
		    <!--当设置好一个分页的显示数据数量时,将数据以cookie的方式存储在浏览器本地-->
		    <select id="s1" onchange='ChangePageItem(this);'>
			    <option value='2'>2</option>
			    <option value='4'>4</option>
			    <option value='6'>6</option>
			    <option value='8'>8</option>
			</select>
		</div>

		<!--引入jQuery文件-->
	    <script src="/static/jquery/jquery-1.11.0.min.js"></script>
	    <script src="/static/jquery/jquery.cookie.js"></script>
	    <script type="text/javascript">
		    //客户端html加载时,获取cookie中存放的分页数据数量。
		    $(function(){
			    var per_item = $.cookie("pager_num");
				if(per_item){
				    $("#s1").val(per_item)
				}
			})
		    function ChangePageItem(arg){
			    //创建或修改cookie值,此处需要导入jquery-1.11.0.min.js或jquery.cookie.js插件
				//key为pager_num,value为30,存储路径为根目录
				//根目录代表全部app的url都可以使用该cookie存储的数据,
				//也可以使用{path:'/web'}的方式进允许某个app访问使用该cookie存储的数据
				var value = $(arg).val();
				$.cookie("pager_num",value,{path:'/'});
				//强制刷新当前页面
				location.reload()
			}
		</script>
	</body>
</html>
配置web views.py文件.读取浏览器存储的cookie值并渲染新的html页面
from django.shortcuts import render
from django.shortcuts import render_to_response
from django.shortcuts import HttpResponse
from web import models
from web import html_helper
#引用mark_safe模块,令html标签等代码内容不干扰正常python逻辑代码
from django.utils.safestring import mark_safe
# Create your views here.
def index(request,page):
    #获取cookie.获取pager_num的值,若未获取到,默认值为5
    per_item = int(request.COOKIES.get('pager_num',5))
    #捕捉page的类型,确保page总是为正整形
    try:
        page = int(page)
    except Exception:
        page = 1
    count = models.Host.objects.all().count()
    pageObj = html_helper.PageInfo(page,count,per_item)
    rcvData = models.Host.objects.all()[pageObj.start:pageObj.end]
    rcvCount = models.Host.objects.all()[pageObj.start:pageObj.end].count()
    pageEle = html_helper.Pager(page,pageObj.all_page_count)
    ret = {'status':'','data':rcvData,'rcvCount':rcvCount,'page':page,'pageEle':pageEle}
    response = render_to_response('web/index.html',ret)
    #设置cookie
    response.set_cookie('pager_num',per_item)
    return response

关于Session

获取session:
request.session[key]
设置session:
request.session[key] = value
删除session:
del request[key]

session使用示例

session示例框架

在这里插入图片描述

配置sessionDemo urls.py文件
from django.contrib import admin
from django.urls import path
from sessionDemo import views

urlpatterns = [
    path('login/', views.login),
    path('index/', views.index),
    path('logout/', views.logout),
]
配置sessionDemo views.py文件。
from django.shortcuts import render
from django.shortcuts import render_to_response
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
import requests
import json
# Create your views here.
def login(request):
    if request.method == "POST":
        user = request.POST.get("username")
        pwd = request.POST.get("password")
        if user == 'dfq' and pwd == '123123':
            #当用户身份合法时,将登陆状态存储到session内
            request.session['is_login'] = {'user':user}
            return redirect('/sessionDemo/index/')
        else:
            return render_to_response('sessionDemo/login.html',{'msg':'用户名或密码错误'})
    return render_to_response('sessionDemo/login.html')
#后台管理的主页面
def index(request):
    #通过session判断当前用户是否是登陆状态
    try:
        is_login = request.session['is_login']
    except Exception:
        return render_to_response('sessionDemo/login.html',{'msg':'非法用户,给我滚回去登陆'})
    if is_login:
        return render_to_response('sessionDemo/index.html',{'username':is_login['user']})
    else:
        return render_to_response('sessionDemo/login.html',{'msg':'非法用户,给我滚回去登陆'})
    
def logout(request):
    #销毁session
    try:
        del request.session['is_login']
    except Exception:
        pass
    return redirect('/sessionDemo/login/')
    
配置sessionDemo login.html文件。系统登录页面
<!doctype html>
<html>
    <head>
	    <!--对页面编码进行设置-->
	    <meta http-equiv="content-type" content="text/html;charset=utf-8">
		<!--兼容IE6浏览器-->
		<meta http-equiv="X-UA-Compatible" content="IE=Edge">
		<title>demo 10</title>
		<style>
			.hide{
			    display:none;
			}
			.clearfix:after{
			    content:".";
				display:block;
				height:0;
				clear:both;
				visibility:hidden;
			}
		</style>

	</head>
	<body>
	    <h1>使用session保存用户会话</h1>
		
		<form method="POST" action="/sessionDemo/login/">
	    <p>用户名:<input name="username" /></p>
		<p>密码:<input name="password" /></p>
		<input  type="submit" value="提交" />
		<label style='color:red;'>{{msg}}</label>
		</form>
		
		<!--引入jQuery文件-->
	    <script src="jquery-1.11.0.min.js"></script>
	    <script type="text/javascript">
		</script>
	</body>
</html>
配置sessionDemo index.html页面。系统主页面
<!doctype html>
<html>
    <head>
	    <!--对页面编码进行设置-->
	    <meta http-equiv="content-type" content="text/html;charset=utf-8">
		<!--兼容IE6浏览器-->
		<meta http-equiv="X-UA-Compatible" content="IE=Edge">
		<title>demo 10</title>
		<style>
			.hide{
			    display:none;
			}
			.clearfix:after{
			    content:".";
				display:block;
				height:0;
				clear:both;
				visibility:hidden;
			}
		</style>

	</head>
	<body>
	    <h1>当前登录用户:{{username}}</h1>
		<form method="POST" action="/sessionDemo/logout/">
		<input  type="submit" value="退出" />
		</form>
		<!--引入jQuery文件-->
	    <script src="jquery-1.11.0.min.js"></script>
	    <script type="text/javascript">

		</script>
	</body>
</html>

cookie与session的区别

  1. cookie存在客户端的浏览器上();session存在服务器上(位置任意指定,如内存、数据库、缓存等)
  2. session用于保持会话(如维持登录状态,无论进行任何操作都能获取到当前用户的登录信息)
  3. session存储的数据有效时间默认是两周
  4. session与cookie通常是混合使用的

跨站请求伪造的使用

django为用户实现防止跨站请求伪造功能,通过中间件django.middleware.CsrfViewMiddleware来完成,而对于Django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件:django.middleware.csrf.CsrfViewMiddleware
局部:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件

配置settings.py文件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

当“‘django.middleware.csrf.CsrfViewMiddleware’,”没有注销时,在Django框架中使用POST方法时,需要用户身份验证。

token:token可以理解为是一段用于用户身份合法性验证的字符串。
request:request又被称为请求上下文对象

配置sessionDemo views.py文件。对上下文对象request封装并返回token

from django.shortcuts import render
from django.shortcuts import render_to_response
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
import requests
import json
#RequestContext进荣誉室了
#from django.template.context import RequestContext

from django.template.context_processors import csrf


# Create your views here.
def login(request):
    if request.method == "POST":
        user = request.POST.get("username")
        pwd = request.POST.get("password")
        if user == 'dfq' and pwd == '123123':
            #当用户身份合法时,将登陆状态存储到session内
            request.session['is_login'] = {'user':user}
            return redirect('/sessionDemo/index/')
        else:
            return render_to_response('sessionDemo/login.html',{'msg':'用户名或密码错误'},context=csrf(request))
    ##(该行荣誉室了)#使用"context_instance=RequestContext(request)",在客户端保存用于用户身份合法性验证的cookie数据    
    #通过csrf(request)对请求上下文对象request封装并返回(其中包含存储在cookie中的csrftoken数据)。
    return render_to_response('sessionDemo/login.html',context=csrf(request))
#后台管理的主页面
def index(request):
    #通过session判断当前用户是否是登陆状态
    try:
        is_login = request.session['is_login']
    except Exception:
        return render_to_response('sessionDemo/login.html',{'msg':'非法用户,给我滚回去登陆'})
    if is_login:
        return render_to_response('sessionDemo/index.html',{'username':is_login['user']})
    else:
        return render_to_response('sessionDemo/login.html',{'msg':'非法用户,给我滚回去登陆'})
    
def logout(request):
    #销毁session
    try:
        del request.session['is_login']
    except Exception:
        pass
    return redirect('/sessionDemo/login/')
    

配置sessionDemo login.html文件,将cookie中的token数据放到form表单中提交

<!doctype html>
<html>
    <head>
	    <!--对页面编码进行设置-->
	    <meta http-equiv="content-type" content="text/html;charset=utf-8">
		<!--兼容IE6浏览器-->
		<meta http-equiv="X-UA-Compatible" content="IE=Edge">
		<title>demo 10</title>
		<style>
			.hide{
			    display:none;
			}
			.clearfix:after{
			    content:".";
				display:block;
				height:0;
				clear:both;
				visibility:hidden;
			}
		</style>

	</head>
	<body>
	    <h1>使用session保存用户会话</h1>
		
		<form method="POST" action="/sessionDemo/login/">
		    <!--csrf_token需要包含在form表单中一起提交-->
		    {% csrf_token %}
			<p>用户名:<input name="username" /></p>
			<p>密码:<input name="password" /></p>
			<input  type="submit" value="提交" />
			<label style='color:red;'>{{msg}}</label>
		</form>
		
		<!--引入jQuery文件-->
	    <script src="jquery-1.11.0.min.js"></script>
	    <script type="text/javascript">
		</script>
	</body>
</html>

token与Ajax结合提交的方法,配置sessionDemo login.html文件

<!doctype html>
<html>
    <head>
	    <!--对页面编码进行设置-->
	    <meta http-equiv="content-type" content="text/html;charset=utf-8">
		<!--兼容IE6浏览器-->
		<meta http-equiv="X-UA-Compatible" content="IE=Edge">
		<title>demo 10</title>
		<style>
			.hide{
			    display:none;
			}
			.clearfix:after{
			    content:".";
				display:block;
				height:0;
				clear:both;
				visibility:hidden;
			}
		</style>

	</head>
	<body>
	    <h1>使用session保存用户会话</h1>
		
		<form method="POST" action="/sessionDemo/login/">
		    <!--csrf_token需要包含在form表单中一起提交-->
		    {% csrf_token %}
			<p>用户名:<input name="username" /></p>
			<p>密码:<input name="password" /></p>
			<input  type="submit" value="提交" />
			<label style='color:red;'>{{msg}}</label>
		</form>
		<input type="button" onclick="Do();"  value="Do it"/>
		<!--引入jQuery文件-->
	    <script src="/static/jquery/jquery-1.11.0.min.js"></script>
	    <script src="/static/jquery/jquery.cookie.js"></script>
	    <script type="text/javascript">
			var csrftoken = $.cookie('csrftoken');
	 
			function csrfSafeMethod(method) {
				// these HTTP methods do not require CSRF protection
				return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
			}
			$.ajaxSetup({
				beforeSend: function(xhr, settings) {
					if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
						xhr.setRequestHeader("X-CSRFToken", csrftoken);
					}
				}
			});
			function Do(){
	 
				$.ajax({
					url:"/sessionDemo/login/",
					data:{id:1},
					type:'POST',
					success:function(data){
						console.log(data);
					}
				});
	 
			}
		</script>
	</body>
</html>

中间件

中间件可以定义四个方法,分别是:

  • process_request(self,request)
  • process_view(self,request,callback,callback_args,callback_kwargs)
  • process_exception(self,request,exception)
  • process_response(self,request,response)
    以上方法的返回值可以是None和HttpResponse对象,如果是None,则继续按照Django定义的规则向下执行,如果是HttpResponse,则直接将该对象返回给用户

admin的使用方法

在创建表后,方便对表的增删改查
Django admin是Django提供的一个后台管理页面,改善管理页面提供完善的HTML和css,使得你在通过model创建完数据库后,就可以对数据进行增删改查,而使用Django admin则需要以下步骤:

创建后台管理员

python manage.py createsuperuser

配置后台管理urls.py

注册和配置Django admin 后台管理页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值