• Django之框架,视图,模板


    day65 2018-06-15

     

    1. Django框架详细介绍

     

    MVC框架和MTV框架(了解)

    Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。

    Django框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架

     

    DjangoMTV模式

           Model(模型):负责业务对象与数据库的对象(ORM)

           Template(模版):负责如何把页面展示给用户

           View(视图):负责业务逻辑,并在适当的时候调用ModelTemplate

    此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的ModelTemplate

    app

            

    命令行创建

    python manage.py startapp app01

    下面围绕这几个点说

    视图系统

    1. 视图 views.py

     

    1. FBV(function base view) 基于函数的视图

    抛出一个问题:

    函数的装饰器能不能直接用来装饰类中的方法

     

    2. CBV(class base view) FBV(function base view)基于类

        

    注意:

    使用CBV时,urls.py中也做对应的修改:

    # urls.py
    url(r'^add_class/$', views.AddClass.as_view()),

     

    Request对象和Response对象

    request对象

    当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。

    Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

     

    官方文档

    请求相关的常用值

    ·        path_info     返回用户访问url,不包括域名

    ·        method        请求中使用的HTTP方法的字符串表示,全大写表示。

    ·        GET              包含所有HTTP  GET参数的类字典对象

    ·        POST           包含所有HTTP POST参数的类字典对象

    ·        body            请求体,byte类型 request.POST的数据就是从body里面提取到的

    属性

    所有的属性应该被认为是只读的,除非另有说明。

        

    3. 上传文件的注意事项:
    
    1. 如果有上传文件,views.py中应该从request.FILES中取上传的文件对象
    
    2. 如果有上传文件,html文件中的form表单一定要加 enctype="multipart/form-data"
    
     
    
    file_obj = request.FILES.get("touxiang")  # 拿到上传文件对象
    
    file_name = file_obj.name  # 拿到文件名
    
    with open(file_name, "wb") as f:  # 在本地新建一个同名文件
    
    for line in file_obj.chunks():  # 从上传的文件对象中一点一点读取数据
    
    f.write(line)  # 写到新建的文件中
    
     return HttpResponse("上传OK")
    
     
    View Code

     

     

    注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:

    request.POST.getlist("hobby")

     

    使用

    传递字符串
    
    from django.http import HttpResponse
    response = HttpResponse("Here's the text of the Web page.")
    response = HttpResponse("Text only, please.", content_type="text/plain")
    
    设置或删除响应头信息
    
    response = HttpResponse()
    response['Content-Type'] = 'text/html; charset=UTF-8'
    del response['Content-Type']
    View Code

    Response对象

    与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse

    HttpResponse类位于django.http模块中

    使用

     

    传递字符串
    
    from django.http import HttpResponse
    response = HttpResponse("Here's the text of the Web page.")
    response = HttpResponse("Text only, please.", content_type="text/plain")
    
    设置或删除响应头信息
    
    response = HttpResponse()
    response['Content-Type'] = 'text/html; charset=UTF-8'
    del response['Content-Type']
    View Code

    属性

    HttpResponse.content:响应内容

    HttpResponse.charset:响应内容的编码

    HttpResponse.status_code:响应的状态码

     

    4. JsonResponse

    Django封装的一个专门用来返回JSON格式数据的方法()

     

    from django.http import JsonResponse

     

    JsonResponse(字典)(默认传字典)

    JsonResponse(列表,safe=False)

    默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

    response = JsonResponse([1, 2, 3], safe=False)

     

    补充一个知识点

    python

     

                       

                                         

    我们在开发中通常需要清除浏览器缓存

     

     

    Django shortcut functions

    renderredirect

    Render 结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

    render()

    结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
    
    参数:
         request:用于生成响应的请求对象。
    
    template_name:要使用的模板的完整名称,可选的参数
    
    context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
    
    content_type:生成的文档要使用的MIME类型。默认为 DEFAULT_CONTENT_TYPE 设置的值。默认为'text/html'
    
    status:响应的状态码。默认为200。
    
     
    
    useing: 用于加载模板的模板引擎的名称。
    
     
    
    一个简单的例子:
    
    from django.shortcuts import render
    
    def my_view(request):
        # 视图的代码写在这里
        return render(request, 'myapp/index.html', {'foo': 'bar'})
    
    上面的代码等于:
    
     
    
    from django.http import HttpResponse
    from django.template import loader
    
    def my_view(request):
        # 视图代码写在这里
        t = loader.get_template('myapp/index.html')
        c = {'foo': 'bar'}
        return HttpResponse(t.render(c, request))
    View Code

    redirect()

    参数可以是:

    ·        一个模型:将调用模型的get_absolute_url() 函数

    ·        一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称

    ·        一个绝对的或相对的URL,将原封不动的作为重定向的位置。

    默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。

    示例:

    你可以用多种方式使用redirect() 函数。

     

    传递一个具体的ORM对象(了解即可)
    
    将调用具体ORM对象的get_absolute_url() 方法来获取重定向的URL:
    
    
    
    from django.shortcuts import redirect
    
     
    def my_view(request):
        ...
        object = MyModel.objects.get(...)
        return redirect(object)
    
    
    
    传递一个视图的名称
    
    def my_view(request):
        ...
        return redirect('some-view-name', foo='bar')
    
    传递要重定向到的一个具体的网址
    
    def my_view(request):
        ...
        return redirect('/some/url/')
    
    当然也可以是一个完整的网址
    
    def my_view(request):
        ...
        return redirect('http://example.com/')
    
    默认情况下,redirect() 返回一个临时重定向。以上所有的形式都接收一个permanent 参数;如果设置为True,将返回一个永久的重定向:
    
    def my_view(request):
        ...
        object = MyModel.objects.get(...)
        return redirect(object, permanent=True)
    
    扩展阅读: 
    
    临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
    
    A页面临时重定向到B页面,那搜索引擎收录的就是A页面。
    
    A页面永久重定向到B页面,那搜索引擎收录的就是B页面。
    View Code

     

    模板

    2. 模板语言(重要)

     

    1. 目前已经学到的模板语言内容

    1. {{变量}}

    2. {% 逻辑操作 %}

    1. for循环

    {% for i in list %}

    {{ i }}

    {% endfor %}

     

    forloop.counter

    forloop.counter0

     

    forloop.last

     

    {% empty %}

     

    2. if判断

    {% if 条件 %}

    条件成立要做的事儿

    {% else %}

    条件不成立要做的事儿

    {% endif %}

    3. 逻辑判断

    1. in 判断

    2. == 判断

     

    1. 模板语言变量相关

    1. 字典的key对应的值

    {{ dic.key}}

    2. 列表按索引取值

    {{ list.1 }}

    3. 对象的属性和方法

    {{ obj.name }}

    {{ obj.dream }}  --> 方法不要加括号

     

    2. Filters (对变量做一些额外的操作)

    1. 内置的filter

     

    语法: {{ value|filter_name:参数 }}

              

    default

    {{ value|default: "nothing"}}

    如果value值没传的话就显示nothing

    length

    {{ value|length }}

    '|'左右没有空格没有空格没有空格

    返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

    filesizeformat

    将值格式化为一个人类可读的文件尺寸(例如 '13 KB''4.1 MB''102 bytes', 等等)。例如:

    {{ value|filesizeformat }}

    如果 value 123456789,输出将会是 117.7 MB

    slice

    切片

    {{value|slice:"2:-1"}}

    date

    格式化

    {{ value|date:"Y-m-d H:i:s"}}

    safe

    Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。

    比如:

    value = "<a href='#'>点我</a>"

    {{ value|safe}}

     

    2. 自定义的filter

     

    1. app下面新建一个Python package,包名必须叫 templatetags

    2. 在上面的包中新建一个python文件,里面定义函数,并且注册到django的模板语言

    from django import template

    # 生成一个用于注册自定义filter方法的实例

    register = template.Library()

     

     

    @register.filter(name="sb")

    def add_sb(value):

    return "{} sb".format(value)

    3. 使用自定义的filter方法

    {% load py文件名 %}

    {{ value|sb }}

    3. tags

     

    for

    <ul>
    {% for user in user_list %}
       
    <li>{{ user.name }}</li>
    {% endfor %}
    </ul>

    for循环可用的一些参数:

     

    Variable

    Description

    forloop.counter

    当前循环的索引值(从1开始)

    forloop.counter0

    当前循环的索引值(从0开始)

    forloop.revcounter

    当前循环的倒序索引值(从1开始)

    forloop.revcounter0

    当前循环的倒序索引值(从0开始)

    forloop.first

    当前循环是不是第一次循环(布尔值)

    forloop.last

    当前循环是不是最后一次循环(布尔值)

    forloop.parentloop

    本层循环的外层循环

    for ... empty

    <ul>
    {% for user in user_list %}
       
    <li>{{ user.name }}</li>
    {% empty %}
       
    <li>空空如也</li>
    {% endfor %}
    </ul>


    if,elifelse

    {% if user_list %}
     
    用户人数:{{ user_list|length }}
    {% elif black_list %}
     
    黑名单数:{{ black_list|length }}
    {% else %}
     
    没有用户
    {% endif %}


    当然也可以只有ifelse

    {% if user_list|length > 5 %}
     
    七座豪华SUV
    {% else %}
       
    黄包车
    {% endif %}

    if语句支持 and or==><!=<=>=innot inisis not判断。

    with

    定义一个中间变量

    {% with total=business.employees.count %}
        {{ total }} employee{{ total|pluralize }}
    {% endwith %}

     

    csrf_token

    这个标签用于跨站请求伪造保护。

    在页面的form表单里面写上{% csrf_token %}

    注意事项

    1. Django的模板语言不支持连续判断,即不支持以下写法:

    {% if a > b > c %}
    ...
    {% endif %}

     

    2. Django的模板语言中属性的优先级大于方法

    def xx(request):
        d = {
    "a": 1, "b": 2, "c": 3, "items": "100"}
       
    return render(request, "xx.html", {"data": d})

    如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个keyitems并且还有默认的 d.items() 方法,此时在模板语言中:

    {{ data.items }}

    默认会取ditems key的值。

     

     

    4. 母版与继承

    1. 定义母版   --> 其他很多页面会用到的共用部分 我们可以提取出来放在单独的一个html文件中

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Title</title>
      {% block page-css %}
      
      {% endblock %}
    </head>
    <body>
    
    <h1>这是母板的标题</h1>
    
    {% block page-main %}
    
    {% endblock %}
    <h1>母板底部内容</h1>
    {% block page-js %}
    
    {% endblock %}
    </body>
    </html>
    View Code

    注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。

     

    2. 在母版中 通过定义不同的 block 等待子页面来替换对应的内容

    3. 在子页面中 通过 {% extends 'base.html '%}来继承已经定义好的母版

    4. 在子页面中通过 block 来实现自定义页面内容     

    通过在母板中使用{% block  xxx %}来定义""

    5. 通常会在母版中定义 子页面专用的 page-css page-js 两个块

       一起定义这两个

    5.组件

    把功能相对独立的html代码 放在一个单独的文件中 作为组件 供其他页面使用

    {% include 'nav.html' %}

     


     

  • 相关阅读:
    JavaScript设计模式-21.命令模式
    JavaScript设计模式-20.责任链模式
    JavaScript设计模式-18.享元模式
    JavaScript设计模式-19.代理模式
    JavaScript设计模式-17.装饰者模式(下)
    JavaScript设计模式-16.装饰者模式(上)
    面向对象之集合ArrayList
    面向对象之继承
    字符串的添加与切割~~~
    面向对象中构造函数的小练习
  • 原文地址:https://www.cnblogs.com/maojiang/p/9189059.html
Copyright © 2020-2023  润新知