django05 视图层、模版层,模板继承

150 阅读5分钟

网页的伪静态

  • 1.将动态网页伪装成静态网页从而提升网页被搜索引擎收录的概率。
    网址像看起来像一个具体的文件路径
    
  • 2.如何实现网页的伪静态?
    path('index.html',view.index)
    

视图层

  • 1.视图函数必须返回一个HttpResponse对象
    render与refirect底层源代码也是继承了HttpResonse类,底层本质都是HttpResponse对象
    render:
        def render(request, template_name, context=None, content_type=None, status=None, using=None):
            content = loader.render_to_string(template_name, context, request, using=using)
            return HttpResponse(content, content_type, status)
     
    refirect:
        def redirect(to, *args, permanent=False, **kwargs):
             redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
             return redirect_class(resolve_url(to, *args, **kwargs))
    HttpResponsePermanentRedirect与HttpResponseRedirect继承的类往上追溯是HttpResonse类
    
  • 2.视图函数返回json格式数据
    user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
    * 将字典以json格式的字符串返回出来
      方法一:
         json_str = json.dumps(user_dict,ensure_ascii=False)
             return HttpResponse(json_str)
             return JsonResponse(user_dict)
      
      方法二:
          from django.http import JsonResponse # 导入该模块
          JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})
          # 序列化非字典类型的数据还需要指定safe参数为False
          
          JsonResponse模块的源代码:
          class JsonResponse(HttpResponse):
          def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs):
              if json_dumps_params is None:
                  json_dumps_params = {}
              data = json.dumps(data, cls=encoder, **json_dumps_params)      
    
  • 3.FBV与CBV
    • FBV(基于函数的视图)
    def index(request):     # 添加函数要开设对应关系
        return HttpResponse()
    
    • CBV(基于类的视图)
    from django import views    # 导入views模块
    class MyView(views.View):   # 继承views模块里的View类(固定模板)
              def get(self, request):
                  return HttpResponse('我是CBV里面的get方法')
              def post(self, request):
                  return HttpResponse('我是CBV里面的post方法')
     # 要给自定义的类做一个对应关系
      path('func/', views.MyView.as_view())
     # CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行
    
  • 4.CBV源码解析*
    * 源码分析入口
      	path('func/', views.MyView.as_view())
    1.绑定给类的as_view方法
         def as_view():
            def view(...):
                pass
            return view
    2.CBV路由匹配本质:跟FBV是一致的
         path('func/', views.view)
    3.访问url的func路由触发view执行
         def view(...):
             obj = cls()
             return obj.dispatch()
      * self点名字时确定对象时谁
    4.dispatch方法
          def dispatch(...):
              func_name = getattr(obj,request.method.lower()) 
              func_name(...)
    

模板层

  • 1.模板语法传值
    方法1:指名道姓      
       优点:节省资源
          return render(request, 'modal.html', {'name':name}) 
    方法2:使用关键字locals()
       优点:简单便捷
          return render(request,'modal.html',locals())
    
  • 2.模板语法的传值
    1.基本数据类型直接传递使用
    """django的模板语法在操作容器类型的时候只允许使用句点符"""
    2.函数名的传递会自动加括号执行并将返回值展示到页面上
    3.使用模板语法,有参函数的传递不会执行也不会显示,模板语法不支持
    
  • 3.有参函数传值
    1.类名的传递也会自动加括号产生对象并展示到页面上
    2.对象的传递则直接使用即可
    3.模板语法会判断每一个名字是否可调用,如果可以则调用
    
  • 4.模板语法过滤器(类似于python内置函数)
    <p>统计长度:{{ s|length }}</p>
    <p>加法运算:{{ i|add:123 }}、加法运算:{{ s|add:'heiheihei' }}</p>
    <p>日期转换:{{ s|date:'Y-m-d H:i:s' }}</p>
    <p>文件大小:{{ file_size|filesizeformat }}</p>
    <p>数据切片:{{ l|slice:'0:10' }}</p>
    <p>字符截取(三个点算一个):{{ s1|truncatechars:6 }}</p>
    <p>单词截取(空格):{{ s1|truncatewords:6 }}</p>
    <p>语法转义:{{ script_tag|safe }}</p>
    <p>语法转义:{{ script_tag1|safe }}</p>
    from django.utils.safestring import mark_safe
    script_tag1 = '<script>alert(666)</script>'
    res = mark_safe(script_tag1)
    
    • 有时候html页面上地数据不一定非要再html上写,也可以在后端编写后通过代码传入
  • 5.django模板语法中的符号有两个:
    {{}}     需要使用数据的时候使用
    {%%}     需要使用方法的时候使用
    
  • 6.模板语法标签(类似于python流程控制)
    if相关:
      {% if 条件 %}   #条件一般是模板语法传过来的数据,直接写名字使用即可
          条件成立执行的代码
      {% elif 条件1 %}
      	条件1成立执行的代码	
      {% else %}
         	条件都不成立执行的代码
      {% endif %}
    for相关:
      {% for i in s %}
          {% if forloop.first %}
              <p>第一次for循环</p>
          {% elif forloop.last %}
              <p>最后一次for循环</p>
          {% else %}
              <p>{{ i }}</p>
          {% endif %}
          {% empty %}
          	  <p>空的,不能for循环</p>
      {% endfor %}
    
  • 7.自定义标签函数、过滤器、inclusion_tag
    • 在自定义标签函数前需要进行以下操作
    如果想自定义,需要先做以下三件事
       1.在应用下创建一个文件夹名字为templatetags
       2.在templatetags文件夹创建任意名称的py文件
       3.在py文件内部编写自定义相关代码
       4.在py文件内需要导入固定代码
            from django.template import Library
            register = Library()     
    

    {% load mytag %}

    • 自定义过滤器
      @register.filter(name='myfilter')
      def my_add(a, b):
          return a + b
          # 过滤器最多只有两个参数
        
      {{ i|myfilter:1 }}
      
    • 自定义标签(函数)
      @register.simple_tag(name='mt')
      def 
      func(a, b, c, d):
          return a + b + c + d
        
      {% mt 1 2 3 4 %}
      
    • 自定义inclusion_tag
      @register.inclusion_tag(filename='it.html')
      def index(n):
          html = []
          for i in range(n):
              html.append('第%s页'%i)
          return locals()
           # 在HTML页面上调用一个inclusion_tag,其会作用于一个html页面(局部),将其插入原来调用的位置
      {% index 10 %}   
      
  • 8.模板的继承
    • 页面要使用与模板相同的模板时,就需要用到模板的继承,可以减少不必要的代码编写
    空的Html文件:
           {% extends 'html文件名' %}   # 全部继承
      * 改一个页面需要在原模板上提前做好标记
    	     {% block 名字 %}             # 标记未来继承时要修改的
      	     模板内容
           {% endblock %} 
      * 继承的页面,先继承全部
           {% block 名字 %}             # 要修改的子模版代码(修改后)
      	     子模板内容
           {% endblock %}
    
    • 1.一般母模板中至少有三个区域让扩展性更高
      • css样式
        {% block css %}
        {% endblock %}
        
      • HTML标签内容
        {% block content %}
        {% endblock %}
        
      • js代码
        {% block js %}
        {% endblock %}
        
    • 子板中还可以使用母板的内容 {{ block.super }}
  • 9.模块的导入
    • 将html页面的某个部分当做模块的形式导入使用
      {% include 'menu.html' %}