首页 > 编程语言 >Python基础day56 Django视图层相关

Python基础day56 Django视图层相关

时间:2023-08-01 19:57:11浏览次数:38  
标签:return get Python res self request 视图 Django def

视图层

三板斧问题

在视图函数中写函数跟普通函数不太一样,Django中使用的是局部的request

所有的视图函数不能够没有返回值,并且返回值还必须是HttpResponse对象

# 错误代码
The view app01.views.index didn't return an HttpResponse object. It returned None instead.

其实我们的三板斧方法返回的都是HttpResponse对象

def index(request):
    return HttpResponse('hello world')

在flask中request使用的是全局的request

from ... import request
def index():
    pass

def func():
    pass

JsonResponse序列化

json格式的数据?

  主要就是实现跨语言数据传输

现在实现跨语言数据传输的都是json,在以前使用的是xml

微信支付朝微信的后端发送参数的时候,使用的就是xml

# json格式的数据特点:
{"username":"kevin","age":18}
# 是以字符串形式保存的

# 之前学的如何序列化?
import json
json.dumps    ------------------->JSON.stringify()
json.loads      ------------------->JSON.parse()

# 在JS中是如何做的
JSON.stringify()
JSON.parse()

在Django中如何去序列化

# js中的对象
obj = new Object() # {}
obj = {} # {}

obj.username = 'kevin' # {'username':'kevin'}

consolo.log(obj.username)

from django.http import JsonResponse
def index(request):
    # return render(request, 'index.html')
    # return HttpResponse("index")
    # 追代码----》点进去这个方法去看源码
    # return render(request, "index.html", context={})
    # return redirect()
    d = {'username': 'kevin哈喽', 'age': 18}
    # In order to allow non-dict objects to be serialized set the safe parameter to False.
    l = [1, 2 , 3, 4]
    # 序列化列表
    return JsonResponse(l,safe=False)
    # 如何去序列化,以前的方法
    import json
    # d_json = json.dumps(d,ensure_ascii=False) # 字符串
    # res = JsonResponse(d_json)
    # print(res)  # <JsonResponse status_code=200, "application/json">
    # return HttpResponse(d_json)
  # 序列化并且转码表示中文
  return JsonResponse(d, json_dumps_params={'ensure_ascii': False})
  

form表单上传文件

普通版本

def ad_files(request):
    # 接收提交的文件数据
    # POST只能够获取到post请求的普通数据,拿不到文件数据
    print(request.POST)  # <QueryDict: {}>
    # 接收文件数据
    print(request.FILES)  # <MultiValueDict: {'my_file': [<InMemoryUploadedFile: 弥豆子.jpg (image/jpeg)>]}>
    if request.method == 'POST':
        # 获取文件数据
        file_obj = request.FILES.get('my_file')
        # 上传
        with open(file_obj.name, 'wb') as z:
            for line in file_obj:
                z.write(line)
    return render(request, 'ad_files.html')

随机文件名版本

# 生成随机字符串
def get_random(request):
    random.seed()  # 重新生成随机数种子
    r_int = str(random.randint(1, 9))
    r_str_upper = str(chr(random.randint(65, 90)))
    r_str_lower = str(chr(random.randint(97, 122)))
    r_str = ''
    for i in range(5):
        c_str = random.choices([r_int, r_str_upper, r_str_lower])
        r_str += ''.join(c_str)
    return r_str

def ad_files(request):
    # 接收提交的文件数据
    # POST只能够获取到post请求的普通数据,拿不到文件数据
    print(request.POST)  # <QueryDict: {}>
    # 接收文件数据
    print(request.FILES)  
# <MultiValueDict: {'my_file': [<InMemoryUploadedFile: 弥豆子.jpg (image/jpeg)>]}>
    if request.method == 'POST':
        # 获取文件数据
        file_obj = request.FILES.get('my_file')
        # 拿到上面写的随机字符串
        ran_str = get_random(request)
        # 将随机字符串和文件名拼在一起,防止上传文件名出现重复
        file_name = ran_str + file_obj.name
        # 上传
        with open(file_name, 'wb') as z:
            for line in file_obj:
                z.write(line)
    return render(request, 'ad_files.html')

request对象的其他前几个方法

def z_request(request):
    print(request.path)  # /z_request/只能拿到地址
    print(request.path_info)  # /z_request/只能拿到地址
    print(request.get_full_path())  # /z_request/?username=kevin&age=11  能拿到地址和后面的参数
    return HttpResponse('z_request')
request.body # 现在先不学,它能够接收浏览器发过来的二进制数据,BBS项目中学

C(class)BV的书写和F(function)BV的写法

# 目前写的都是 FBV:function based view 基于函数的师徒
# 在视图文件中书写类 CBV: class based view 基于类的视图
'''
postman的官网地址:https://www.postman.com/downloads/
apizza的挂网地址:http://www.apizza.net/
'''
# 所有的类必须继承django的view类
from django.views import View
# 路由写法
    # CBV的路由
    url('^login/', views.MyLogin.as_view()),   

class MyLogin(View):
    # 类里面的方法名字不能够随便写,目前只能写get post等
    # 访问这个地址必须是get请求方式
    def get(self, request):
        # get() takes 1 positional argument but 2 were given
        print("get")
        return HttpResponse("get")

    # 访问这个方法必须是psot请求方式
    # 通过form表单发送post请求
    # 出了form表单,我们还可以使用工具来模拟
    def post(self,request):
        print("post")
        return HttpResponse("post")

CBV的源码分析

# 我们第一次看Django的源码,面试题:你都看过Django的哪些源码,简单说说?

# CBV的源码、settings的源码、权限、频率、认证的、签发token的源码

看源码的步骤是先找到源码的入口
CBV的入口在哪里呢?
path('login/', views.MyLogin.as_view()),

views.MyLogin.as_view()

"""
    类名可以调用哪些方法:
        1. 方法被@classmethod装饰器修饰的方法
            类名来调用类方法有什么特殊之处:
                会把类名自动当成第一个参数传递给方法的第一个形参cls
                对象调用方法把对象自己当成第一个参数传给方法的第一个形参self
            
        2. 被@staticmethod装饰器修饰的方法
"""
# 回头复习面向对象的方法调用

# 第一步
@classonlymethod
    def as_view(cls, **initkwargs):
        # cls:MyLogin
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get
            self.setup(request, *args, **kwargs)
            if not hasattr(self, 'request'):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            return self.dispatch(request, *args, **kwargs)
    
        return view
    
# 第二步:
path('login/', View.view),

# 第三步:
当请求来的时候,开始匹配路由login,就会调用View.view()

# 第四步
        def view(request, *args, **kwargs):
            # self = MyLogin(**initkwargs)
            self = cls(**initkwargs)
            """
                self: MyLogin()
            """
            return self.dispatch(request, *args, **kwargs) # 这句话是最重要的
 # 第五步:self.dispatch(request, *args, **kwargs) 
# 第六步:找到了View类里面的dispatch方法
第七步:
    def dispatch(self, request, *args, **kwargs):
            # getattr: 反射
            # 反射
            # getattr setattr delattr hasattr
            # handler = getattr(self, 'get', self.http_method_not_allowed)
            # handler = getattr(self, 'post', self.http_method_not_allowed)
            # handler就是方法名,对象
            # hander = get
            # hander = post
            # hander = self.http_method_not_allowed
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
    

# 问题:如何让我写的CBV类只支持get请求或者只支持post请求?
源码是用来看的,不是用来改的,有时候也能够改,但是你不行,你这个阶段先不要想着改人家源码的


class MyLogin(View):
    http_method_names = ['get',]
    # 类里面的方法名字不能够随便写,目前只能写get post等
    # 访问这个地址必须是get请求方式
    def get(self, request):
        # get() takes 1 positional argument but 2 were given
        print("get")
        return HttpResponse("get")

模板层

模板变量之分配

模板中取值一定要使用句点符  .

模板中的函数一定不能够加括号

# views
def func(request):
    d = {'username': 'jack'}
    a = 1
    b = 1.1
    c = 'hello boy'
    e = [1, 2, 3]
    f = (1, 2, 3)
    g = True
    h = {1, 2, 3}

    def index():
        print('index')
        return 'index'

    class login():
        print('login')

        def index(self):
            return 'login.index'

    return render(request, 'func.html', locals())

# html
<body>
{{ a }}
{{ b }}
{{ c }}
{{ d }}
{{ e.1 }}
{{ f.2 }}
{{ g }}
{{ h }}
{{ index }}
{{ login.index }}
</body>
# 结果
# 1 1.1 hello boy {'username': 'jack'} 2 3 True {1, 2, 3} index login.index

模板之过滤器

# Django自带的过滤器有好几十、但是我们没必要全部记住,只需要记住几个就行了
语法:
    {{ obj|过滤器名称:参数 }}  变量名字|过滤器名称:变量

案例:
# html
{#判定res的值,为False就执行default后面的#}
{{ res|default:'你好啊' }}
{#计算长度,无法计算就返回0#}
{{ res_len|length }}
{#返回数字对应的'人类可读的'文件大小#}
{{ res_size|filesizeformat }}
{#前段返回日期格式时间#}
{{ res_data|date:'Y-m-d H:m:s' }}
{#截取字符串,后面的用...代替#}
{{ res_trunc|truncatechars:9 }}
{#将字符串形式的前端语句生效#}
{{ res_safe|safe }}
{{ res_html }}
 
# views
def z_filter(request):
    res = True
    res_len = 'hello'
    res_size = 199999
    import datetime
    res_data = datetime.datetime.now()
    res_trunc = 'hello good boy'
    # 后端生效前端代码
    res_safe = '<h1>safe</h1>'
    # 第二种方式
    from django.utils.safestring import mark_safe
    res_html = mark_safe('<h2>html</h2>')
    return render(request, 'z_filter.html', locals())

 

标签:return,get,Python,res,self,request,视图,Django,def
From: https://www.cnblogs.com/zfq132/p/17598926.html

相关文章

  • python采集爬虫数据,API接口调用获取淘宝天猫,拼多多,1688等平台商品详情
    Python技术爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者);它是一种按照一定的规则,自动地抓取网络信息的程序或者脚本。如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,他们沿着蜘蛛网抓取自己想要的......
  • 什么是gil锁、python的垃圾回收机制是什么样的?解释为什么计算密集型用多进程,io密集型
    目录1什么是gil锁-全局解释器锁:gil锁的作用是什么?为什么要有gil锁?2python的垃圾回收机制是什么样的?-引用计数-标记清除-分代回收3解释为什么计算密集型用多进程,io密集型用多线程计算密集型任务:I/O密集型任务:总结:1什么是gil锁-全局解释器锁:它的本质就是一个大的互斥锁,它......
  • 【ArangoDb踩坑】arango视图更新操作注意
    一、问题ping协议的覆盖率字段一直更新有误。二、原因ArangoDBviews中的属性commitIntervalMsec默认为1000毫秒,该属性限制了提交视图数据存储更新后必须要等待指定毫秒数才能查询文档,否则数据就是不可见的。snmp、ping、rping、telemetry四种协议是轮流更新的,其中snmp、ping......
  • 视图层
    三板斧问题在视图函数写函数跟普通函数不一样,它需要传一个request参数给形参,而这个参数只能在函数中局部使用所有视图函数不能够没有返回值,并且返回值还必须是httpresponse对象Theviewapp01.views.indexdidn'treturnanHttpResponseobject.ItreturnedNoneinstead.......
  • Python实现批量将ppt转换为pdf
    这是一个Python脚本,能够批量地将微软Powerpoint文件(.ppt或者.pptx)转换为pdf格式。使用说明1、将这个脚本跟PPT文件放置在同一个文件夹下。2、运行这个脚本。全部代码1234567891011121314151617181920212223import comtypes.clientimport osdef init_powerpoint():powerpoint =......
  • python如何制作自己的模块
    你可以按照以下步骤制作自己的Python模块:1.创建一个新的.py文件,并定义你自己的函数或类。2.编写文档字符串docstring,说明该函数或类的作用、参数和返回值说明等。3.给你的函数或类添加恰当的注释。4.将该.py文件放在工程目录的一个新文件夹中,这个文件夹就是你的模块。5.在你......
  • python如何制作自己的模块
    你可以按照以下步骤制作自己的Python模块:1.创建一个新的.py文件,并定义你自己的函数或类。2.编写文档字符串docstring,说明该函数或类的作用、参数和返回值说明等。3.给你的函数或类添加恰当的注释。4.将该.py文件放在工程目录的一个新文件夹中,这个文件夹就是你的模块。5.在你......
  • 【Python小随笔】Pillow简单示例(图片添字,图片覆盖图片,复杂验证码...)
     简单创建添加文字到图片fromPILimportImage,ImageDraw,ImageFont,ImageFilter#导入PIL库中的相关模块importrandom#导入random库#简单的添加文字"""mode:图片模式,指定了每个像素点的颜色组织方式。常用的模式有:'1':二值图像,每个像素点只有黑和白两种颜......
  • Python Jenkins-调用_get_view_jobs方法获取指定视图下的Job名称
    一、pythonjenkins库api简介1.1、连接Jenkins服务器server=jenkins.Jenkins(url,username=None,password=None,timeout=30)url:指的是所连接的Jenkins的网络地username/password:username/password默认值是None,在内网中不传参数也是可以连接成功的,但应该......
  • 升级到python3以后yum报错
    升级完python后(python2升级到python3,并且将原来的/usr/bin下的python软连接给替换成python3的了),执行yum安装或查看命令都会产生这个错误:[root@localhostbin]#yumFile"/usr/bin/yum",line30exceptKeyboardInterrupt,e:^SyntaxErr......