Day 58 django 视图层 模板层

Day 58 django

1、网页伪静态

将动态网页伪装称静态网页 从而提升网页被搜索 收录的概率

表现形式就是网址看着像是一个具体的文件路径

path('index.htm',views.index)

2、视图层

2.1、视图函数返回值 问题

视图函数必须返回一个HTTPResponse对象
注意HTTPResponse 其实是一个类
HttpResponse

class HttpResponse(HttpResponseBase):

render

def render(request, template_name, context=None, content_type=None, status=None, using=None):
    #查看源码 发现 返回的是 HttpResponse
    return HttpResponse(content, content_type, status)

redirect

def redirect(to, *args, permanent=False, **kwargs):
    
    #查看 源码 得知 redirect 中 三元表达式  返回 其中的结果 然后我们继续深入 
  	redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
    return redirect_class(resolve_url(to, *args, **kwargs))
#深入 后发现 他最后 还是 继承了 HttpResponse
class HttpResponseRedirectBase(HttpResponse):

2.2、视图函数返回json格式数据

利用json模块 先序列化 然后 返回

from django.http import JsonResponse  # 可以导入 jsonRespons 直接可以 序列化字典
def func2(request):
   user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
   json_str= json.dumps(user_dict,ensure_ascii=False)
   return HttpResponse(json_str)
   return JsonResponse(user_dict)

查看JsonResponse 源码 查找 中文 取消编码 方法

ef __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                 json_dumps_params=None, **kwargs):
        if safe and not isinstance(data, dict):
            raise TypeError(
                'In order to allow non-dict objects to be serialized set the '
                'safe parameter to False.'
            )
        if json_dumps_params is None:  #给这个 参数 传一个 字典 
            json_dumps_params = {}
        kwargs.setdefault('content_type', 'application/json')
        #那么 data 数据 在 序列化的时候 后面 就会 得到一个 关键字 参数 那么 这个字典 就可以 是 {'ensure_ascii':False}
        #然后 一关键字参数 传给dumps 来 取消 编码
        data = json.dumps(data, cls=encoder, **json_dumps_params)
        super().__init__(content=data, **kwargs)

序列化 非字典类型数据 还需要指定 safe参数 为False

 JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})

2.3、form表单携带文件数据

form表单 需要具备的条件

  1. method属性必须是post
  2. enctype属性值必须是multipart/form-data

获取表单数据

def func1(request):
    if request.method=='POST':
        print(request.POST)

    return render(request,'login.html')


#获取到的 只是拿到文件 名称 并未 文件数据
<QueryDict: {'file': ['微信图片_20220824171248.jpg'], '提交': ['提交']}>

获取 文件携带 数据的操作

  • 前端 必要操作
    enctype="multipart/form-data"

    <form action="/func1/" method="post" enctype="multipart/form-data">
    
  • 后端操作

    request.FILEs

    print(request.FILES) #获取 列表 套对象
    file_obj=request.FILEs.get('file')
    
  • 获取 的是文件迭代器对象 可以点name 方法 获取文件名 然后通过 for循环 写入

    def func1(request):
        if request.method=='POST':
            print(request.FILES)
            file_pbj=request.FILES.get('file')
            with open(file_pbj.name,'wb')as f:
                for data in file_pbj:
                    f.write(data)           
    	return render(request,'login.html')
    

2.4、FBV与CBV

FBV:基于函数的视图

#views
def func(request):
    return HttpResponse()
#urls
path('index/',views.index)

CBV:基于类的视图

#views
from django import views

class Myviews(views.View):
    def get(self,request):
        return HttpResponse('CBV GET方式')
    def post(self,requset):
        return HttpResponse('CBV,POST方式')
    
#urls
path('func3/',views.Myviews.as_view()
  • CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行

CBV 源码分析

  1. 源码分析路口

    path('func3/',views.Myviews.as_view()
    
  2. 绑定类的as_view方法

      @classonlymethod		
      def as_view(cls, **initkwargs):  # 通过 装饰语法 将其定义为类的属性方法
          ...
          def view(request, *args, **kwargs):
              self = cls(**initkwargs)
              ...
              return self.dispatch(request, *args, **kwargs)
          ...
         	return view  #最后 返现 返回的是 view函数
    
  3. 发现CBV路由匹配的本质 跟FBV是一致的

    			#都是 点 函数的形式
    path('func/', views.view)  #都是 通过访问路由 然后 调用函数
    
  4. 访问到func 触发view函数执行

    def view(request, *args, **kwargs):
        self = cls(**initkwargs)  #类产生一个对象 就是 我们写的类产生的对象, cls 是我们自己写的类 点 as_views 传进来的
        ...
        #最后 对象 点 dispatch 先从 对象本身找该方法 没有 再到父类找
        return self.dispatch(request, *args, **kwargs)
    
  5. 研究dispatch方法

    # http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    def dispatch(self, request, *args, **kwargs):
        #  请求方式小写字符串  在不在 后面这个列表里面面
        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)
    

3、模板层

3.1、模板语法传值

方式一:指名道姓的传

return render(request,'modal.html',{'name':name})

方式二:关键字locals()

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

3.2、模板语法值得范围

基本数据类型直接传递使用

函数名:
函数名的传递会自动加括号执行 并将返回值展示到页面上
注意函数如果有参数则不会执行也不会展示 模板语法不支持有参函数

类名:
类名得传递也会自动加括号产生对象 并展示到页面上

对象:
对象得传递则直接使用即可

规律:
模板语法会判断每个名字是否可调用 如果可以则调用

3.3、模板语法过滤器

类似于python的内置函数

<p>同级长度:{{ s|length }}</p>   
<p>数字加法运算:{{ i|add:100 }}</p>   
<p>字符串拼接:{{ s|add:'python' }}</p>  
<p>日期转换:{{ res|date:'Y-m-d H:i:s' }}</p>
<p>文件大小:{{ file_size|filesizeformat }}</p>
<p>数据切片:{{ l|slice:'0:4' }}</p>   
<p>字符截取:(按字符个数截取 三个点 算一个){{ s|truncatechars:6 }}</p>   #超出范围 会返回完整的数据 
<p>单词截取:(三个点不算 按空格截取){{ s|truncatewords:2 }}</p>
<p>语法转义:{{ script|safe }}</p>   # 重点
<p>语法转义 (后端转):{{ script_mak }}</p>

后端语法转义

from django.utils.safestring import mark_safe
script_mak=mark_safe('<h2>我在干饭</h2>')

<p>语法转义 (后端转):{{ script_mak }}</p>

3.4、模板语法标签

类似于 python中流程控制

django 模板语法中符号 就两个 {{}} {% %}
需要使用数据的时候{{}}
需要使用方法的时候{% %}

分支结构

# if...elif..else
{% if '' %}  # 条件 一般是模板语法传过来的数据 直接写名字就行 不需要双大括号
    <p>哈哈哈</p>
{% elif '2'%}
    <p>嘿嘿嘿</p>
{% else %}
    <p>呵呵呵</p>
{% endif %}

for循环

{% for re in s %}
    {% if forloop.first %}
        <p>这是第一次</p>
     {% elif forloop.last %}
        <p>这是最后一次</p>
    {% else %}
         <p> {{ re }}</p>
    {% endif %}
    {% empty %}
        <p>是空的无法循环</p>
{#    {{ forloop }}#}
{% endfor %}

3.5、自定义标签、过滤器、inclusion_tag

如果想自定义 必须做以下三件事

  1. 在应用下创建名为templatetags文件夹

  2. 在该文件夹传进啊任意名称的py文件

  3. 在该py文件内编写自定义相关代码

    from django.template import Library
    register = Library()
    

3.6、自定义过滤器

在temp latetags 文件夹下创建任意名称py文件

过滤器 至多只能有两个函数

from django.template import Library

register = Library()


# 自定义 过滤器
@register.filter(name='myfilter')
def my_add(a, b):
    return a + b

引用过滤器

{% load mytags %}  #引用
{{ i|myfilter:1 }}

3.7、自定义标签函数

@register.simple_tag(name='mt')
def func(a, b, c, d):
    return a + b + c + d

引用函数

{% load mytags %}
{% mt 1 2 3 4 %}

3.8、自定义inclusion_tag

@register.inclusion_tag(filename='it.html')
def index(n):
        html = []
        for i in range(n):
            html.append('第%s页'%i)
        return locals()

引用函数

3.9、模板继承

将要 变动的 内容 利用block包起来

#模板 继承 母板内容
{% extends 'html文件名' %} # 继承了 就可以 获取的 该文件 所有内容

{% block 名字 %}
模板内容
{% endblock %}


{% block 名字 %}  #创建标记
子板内容
{% endblock %}
一般情况下母板中至少应该有三个区域使得扩展性更高!!!

{% block css %}
{% endblock %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}
{子板中 可以使用母版的内容}

模板 导入到 母版

将html页面的某个部分当做模块的形式导入使用
{% include 'menu.html' %}  #只能是 部分
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值