自动化运维Python系列之Django进阶操作

FBV && CBV

FBV、CBV是Django视图路由处理模型,当用户请求送达路由系统URL后,由其转发给视图view来分析并处理

// FBV    function base views 
// CBV    class base views

区别就是一个直接用函数驱动,一个用类驱动,两者在使用上存在一些区别

1)FBV

URL中根据路由匹配直接转发给视图中的某一个处理函数

urlpatterns = [
    url(r‘^home/‘, views.home),
]

视图函数接受到请求后需要我们人为判定请求类别,默认都是以GET请求

from django.shortcuts import HttpResponse
def home(request):
    if request.method == "POST":
        pass
return render(request, ‘home.html‘)
    if if request.method == "GET":
pass
return render(request, ‘home.html‘)

2)CBV

CBV路由要对应写成如下形式

urlpatterns = [
    url(r‘^home/‘, views.Home.as_view()),
]

视图模块中要导入固定View模块并且Home类要继承View

form django.views import View
class Home(View):
     # 自定义CBV最大的好处就是能够在处理请求之前或者之后做一些我们自定义操作
     # dispatch是Django中处理请求方法 相当于定制了dispatch(原理是通过反射)
     def dispatch(self, request, *args, **kwargs):
               printf(‘before‘)
               # 调用父类方法
               result = super(Home, self).dispatch(request, *args, **kwargs)
               printf(‘after‘)
               return result
  
     # 这里我们就不需要自己判断请求类型了 Django自动执行对应方法
     def get(self,request):
               printf(request.method)
               return render(request, ‘home.html‘)
  
     def post(self,request):
               print(request.method)
               return render(request, ‘home.html‘)

HTTP请求处理

在Django视图模块Views中,除了处理GET、POST请求外,还可能要处理HTTP请求头中包含的其他一些客户端数据,比如匹配客户端浏览器类型等;

我们处理的常见请求

// GET请求
request.GET
// POST请求
request.POST
// 处理文件上传请求
request.FILES
// 处理如checkbox等多选 接受列表
request.getlist
// 查看请求类型
request.method
// 查看请求源地址
request.path_info

request.FILES文件上传

由于request.FILES比较特殊,在文件上传后,通过Django的request.POST.get()取到的只是文件名字符串,我们可以自定义一个文件上传方法

1)在form表单属性里面加enctype属性

<form action="/login/" method="POST" enctype="multipart/form-data"></form>
<input type="file" name="a_file"></input>

2)Views中自定义上传

import os
obj = request.FILES.get("a_file")
printf(obj)
# 在Django工作目录新建upload存放文件
file_path = os.path.join(‘upload‘, obj.name)
f = open(obj.name, mode="wb")
# chunks()方法是Django内部处理文件上传的一个产生器 负责将数据分块
for i in obj.chunks():
     f.write(i)
f.closer()

HTTP_USER_AGENT

我们以‘HTTP_USER_AGENT‘为例来看看Django怎么处理HTTP请求头中某个有用的数据

from django.core.handlers.wsgi import WSGIRequest
 
# request中封装了所有请求信息,但是我们怎么得到其中的数据?
def index(request):
    print(type(request))
    print(request.environ)
    return render(request, ‘index.html‘)

request中就有我们想要的数据,request是某个类的实例化,所以我们可以去创建他的类里面看看,得到

<class ‘django.core.handlers.wsgi.WSGIRequest‘>

导入该WSGIReques模块,查看源代码很容易就发现了environ变量,该变量中就有我们需要查看的数据

打印出来,下面就是所有的客户请求数据了

找出来,做可以做相应处理了

from django.core.handlers.wsgi import WSGIRequest
printf(type(request))
printf(‘request.environ‘)
for k,v in environ.items()
    printf(k,v)
printf(request.environ[‘HTTP_USER_AGENT‘])

Cookie

Cookie用来验证用户身份信息,在Django中cookie使用要注意的就是cookie的获取和设置,还有就是salt的对cookie加密功能

设置cookie

当在视图函数里面给客户端返回数据时添加cookie信息

def login(request):
   
    if request.method == "POST":
        u = request.POST.get(‘username‘)
        p = request.POST.get(‘pwd‘)
        dic = user_info.get(u)
        if not dic:
            return render(request,‘login.html‘)
        if dic[‘pwd‘] == p:
res = redirect(‘/index/‘)
// 或者 render(request...)
res.set_cookie(‘username111‘,u)
return res

当用户成功登陆后,以后每次访问都会带cookie请求

设置cookie参数

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt=‘加密‘,...)
    参数:
        key,              键
        value=‘‘,         值
        max_age=None,     超时时间
        expires=None,     超时时间(IE requires expires, so set it if hasn‘t been already.)
        path=‘/‘,         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
   
response = render(request,‘index.html‘)
response = redirect(‘/index/‘)
// 设置cookie,关闭浏览器失效
response.set_cookie(‘key‘,"value")
// 设置cookie, N秒只有失效
response.set_cookie(‘username111‘,"value",max_age=10)
// 设置cookie, 截止时间失效
import datetime
current_date = datetime.datetime.utcnow()
current_date = current_date + datetime.timedelta(seconds=5)
response.set_cookie(‘username111‘,"value",expires=current_date)
response.set_cookie(‘username111‘,"value",max_age=10)

获取cookie

request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None)
    参数:
        default: 默认值
           salt: 加密盐
        max_age: 后台控制过期时间

我们还可以通过j s控制cookie,实现一个控制页面自定义分页数的功能

<div>
    <select id="ps" onchange="changePageSize(this)">
        <option value="10">10</option>
        <option value="30">30</option>
        <option value="50">50</option>
        <option value="100">100</option>
    </select>
</div>
<div class="pagination">
    {{ page_str }}
</div>
// 直接在js中操作cookie需要使用到jquery.cookie插件 
<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
    $(function(){
            // path 控制cookie参数生效页面范围
            var v = $.cookie(‘per_page_count‘, {‘path‘: "/user_list/`"});
            $(‘#ps‘).val(v);
    });
    function changePageSize(ths){
        var v = $(ths).val();
        console.log(v);
        $.cookie(‘per_page_count‘,v, {‘path‘: "/user_list/"});
        location.reload();
    }
</script>

用户登录验证

对于FBV 我们可以直接使用python的装饰器进行函数装饰

def auth(func):
    def inner(reqeust,*args,**kwargs):
        v = reqeust.COOKIES.get(‘username111‘)
        if not v:
            return redirect(‘/login/‘)
        return func(reqeust, *args,**kwargs)
    return inner
    
@auth
def index(reqeust):
    # 获取当前已经登录的用户
    v = reqeust.COOKIES.get(‘username111‘)
    return render(reqeust,‘index.html‘,{‘current_user‘: v})

对于CBV 我们可以通过控制dispath函数来达到控制请求处理

// 使用ethod_decorator进行装饰 name参数表示控制的具体方法
@method_decorator(auth,name=‘dispatch‘)
class Order(views.View):
  
    // 也可以在类内部操作
    # @method_decorator(auth)
    # def dispatch(self, request, *args, **kwargs):
    #     return super(Order,self).dispatch(request, *args, **kwargs)
  
    // 对方法一个个装饰一般不太推荐
    # @method_decorator(auth)
    def get(self,reqeust):
        v = reqeust.COOKIES.get(‘username111‘)
        return render(reqeust,‘index.html‘,{‘current_user‘: v})
  
    def post(self,reqeust):
        v = reqeust.COOKIES.get(‘username111‘)
        return render(reqeust,‘index.html‘,{‘current_user‘: v})
时间: 2024-11-03 22:04:01

自动化运维Python系列之Django进阶操作的相关文章

自动化运维Python系列之Django信号、缓存操作

Django信号 Django内部提供了一种"信号强度"处理机制,简单理解就是当Django在接收到请求后内部做某些特定操作前发出信号,提醒一些接受者或者做操作,这样的好处就是方便程序定制小功能插件,也是对本身框架的一种节藕操作 1)Django的内置信号 Model signals     pre_init                # django的modal执行其构造方法前,自动触发     post_init               # django的modal执行其构

自动化运维Python系列之Django路由系统、Ajax请求

路由系统 路由系统负责分析处理用户请求网址内容,向后视图函数分发处理任务,根据对应的处理函数处理完成后给用户return模板渲染结果:路由系统分类很多,常见的有基本单一路由,正则路由,带额外参数路由,二层三层路由还有通过反射机制来完成的动态路由. 1)单一路由 url(r'^admin/', admin.site.urls) 2)基于正则的路由 url(r'^detail/(\d+)/', views.detail), url(r'^detail2/(?P<p1>\d+)/(?P<x2&

自动化运维Python系列之Django CSRF跨站请求伪造、中间件

CSRF CSRF,跨站请求伪造是一种挟持用户在当前已登陆的web站点应用程序上执行非本意的操作攻击方法,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品). Django的CSRF中间件验证就可以有效地杜绝此类恶意攻击,原理就是Django在内部会对通过验证请求的客户端再做一次加密验证,该加密方式只有Django自己知道,客户端即使携带session反解密CSRF不成功也会拒绝访问:这是Django生

自动化运维Python系列(一)之基础篇

Python介绍 Python是由创始人吉多·范罗苏姆(Guido van Rossum)在1989年圣诞节假期期间,为了打发时间,构思出来的一个新的脚本解释器.由于Guido在开发Python语言过程中,借鉴了很多ABC语言特性,所有后来包括Guido自己也那么认为,Python语言的前身就是ABC语言. Python是一门面向对象的.动态解释型强定义语言:Python崇尚简洁.优美.清晰,是一门优秀的被广泛使用的语言. 在2015年以前,最流行的Python版本还是2.4,但是由于Pytho

自动化运维Python系列之ForeignKey、relationship联表查询

一对多和多对多 数据库表结构设计是程序项目开发前的重要环节,后期数据库操作都是围绕着这个已经设计好的表结构进行,如果表结构设计有问题,整个程序项目就有存在需要整个推翻重构的风险... 数据库表结构除了简单的单表操作以外,还有一对多.多对多等. 一对多 基于SQLAlchemy我们可以先创建如下结构的2张表,然后来看看具体怎样通过外键ForeignKey或者relationship联表操作 创建表 from sqlalchemy.ext.declarative import declarative

自动化运维Python系列(七)之Socket编程

了解知识点TCP\IP 要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准, 从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族.不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中(数据链路层和物理

自动化运维Python系列(四)之装饰器和生成器

装饰器 在理解什么事装饰器之前,我们需要理解:函数也是一个对象,可以赋值给变量,通过变量来调用 def f1():     print('2016') d = f1 d() 输出: 2016 那么装饰器的作用就是在不改变原函数的前提下,调用这些函数,并且为函数增加我们需要的新功能. 我们平时在编写好很多独立函数模块以后,突然需要在每个模块内添加一个功能,比如: def f1():     print('F1') def f2():     print('F2') def f3():     pr

自动化运维Python系列之消息队列RabbitMQ

RabbitMQ RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有很多公开标准(如 COBAR的 IIOP ,或者是 SOAP 等),但是在异步消息处理中却不是这样,只有大企业有一些商业实现(如微软的 MSMQ ,IBM 的 Websphere MQ 等),因此,在 2006 年的 6 月,Cisco .Redhat.iMatix 等联合制定了 AMQP 的

自动化运维Python系列之Memcache、Redis操作

Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信. Memcached安装 wget http://memcached.org/latest tar -zxvf memcach