• 15 Jun 18 Django


    15 Jun 18

    今日内容(Django框架详细介绍)

    https://www.cnblogs.com/liwenzhou/p/8296964.html

     

    1. MVC(model view controller)框架和MTV(model template view)框架: 耦合性低、重用性高、生命周期成本低

     

       Django的MTV模式

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

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

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

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

    2. Django视图系统views.py: 接收web请求request,并返回web响应responseHttpResponse,render,redirect等)

      http://www.cnblogs.com/liwenzhou/articles/8305104.html

     

       # 当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象(一般使用request参数承接这个对象),该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。每个视图负责返回一个HttpResponse对象。

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

     

           def add_class(request):

               if request.method == "POST":

                   class_name = request.POST.get("class_name")

                  models.Classes.objects.create(name=class_name)

                   return redirect("/class_list/")

               return render(request, "add_class.html")

     

            #在urls中需如下调用

            url(r'^publisher_list/', views.add_class),    # FBV的注册方式

     

            抛出一个问题:函数的装饰器能不能直接用来装饰类中的方法

     

        2. CBV(class base view) 基于类的视图

     

           from django.views import View

           class AddClass(View):

               def get(self, request):

                   return render(request, "add_class.html")

               def post(self, request):

                   class_name = request.POST.get("class_name")

                  models.Classes.objects.create(name=class_name)

                   return redirect("/class_list/")

     

           #在urls中需如下调用

           url(r'^publisher_list/', views.AddClass.as_view()),  # CBV的注册方式

     

        # 具体用FBV还是CBV看需求。一般如果情况复杂,可考虑CBV,使结构更清晰

     

        3. request请求相关的常用值

           a. path_info        返回用户访问url(不包括域名)的路径,无参数

           b. get_full_path()  回用户访问url(不包括域名)的路径,和参数

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

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

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

           f. body             请求体中的数据,byte类型request.POST的数据就是从body里面提取到的;GET的为b'';POST的为b'name=****'

     

        #补充,如果一个项目有多个app。在urls.py导入时,可以给不同app中的views.py文件取别名,进而引用。

         from app02 import views as v2

     

        4. 上传文件的注意事项:

            1. 如果有上传文件,views.py中应该从request.FILES中取上传的文件对象。

               # request.POST取出的是字符串['hlw.png'],不是上传的文件对象。

            2. 如果有上传文件,html文件中的form表单一定要加enctype="multipart/form-data"

               # 若不加,取出的是一个空的类似字典的对象 ,不是上传的文件对象。

               换言之,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。

            3. chunks()是django帮忙封装的优化方法,可以考虑使用。

     

            # views.py

            def upload(request):

                if request.method == "POST":

                    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 render(request, "upload_demo.html")

     

            # .html

            <form action="/upload/" method="post" enctype="multipart/form-data">

                <input type="text" name="username">

                <input type="file" name="touxiang">

                <input type="submit" value="提交">

            </form>

     

        5. JsonResponse对象

          Django封装的一个专门用来返回JSON格式数据的方法;是HttpResponse的子类

     

            import json

            HttpResponse(json.dumps(字典))  # HttpResponse()中只能传字符串

     

            from django.http import JsonResponse

            JsonResponse(字典)  # JsonResponse()默认只接收字典类型

            #以上两种方式,得到的结果相同

     

            JsonResponse(列表,safe=False)  # 默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

     

        6. Django shortcut functions之render()

           #参数

           request: 用于生成响应的请求对象。

           template_name:要使用的模板的完整名称,可选的参数

           context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

           content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。默认为'text/html'

           status:响应的状态码。默认为200。

           using: 用于加载模板的模板引擎的名称。  #django支持第三方模版方法,如果使用其他模板,可通过using设置

     

        7. Django shortcut functions之redirect()

           默认情况下,redirect()返回的是临时重定向。若设置permanent=True将返回永久重定向。

     

           临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。

           A页面临时重定向到B页面,那搜索引擎收录的就是A页面。

           A页面永久重定向到B页面,那搜索引擎收录的就是B页面。

     

    3. 模板语言

       http://www.cnblogs.com/liwenzhou/p/7931828.html

     

        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. == 判断

     

        2. 模板语言变量相关(点所有)

            1. 字典的key对应的值

                {{ dic.key}}

            2. 列表按索引取值

                {{ list.1 }}

            3. 对象的属性和方法

                {{ obj.name }}

                {{ obj.dream }}  --> 方法不要加括号,django自动帮助补全拼接

     

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

           {{ value|filter_name:参数}}  # '|'左右没有空格没有空格没有空格

     

            1. 内置的filter

               {{ value|default: "nothing"}}  # 如果value值没传的话就显示nothing

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

               {{ value|filesizeformat }}  # 如果value 是123456789,输出将会是117.7 MB。

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

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

               {{ value|safe}}  # 告诉Django这段代码是安全的不必转义。

               # 为保证安全,Django的模板中会对HTML标签和JS等语法标签进行自动转义。若不希望转译,可设置safe

     

            2. 自定义的filter

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

     

                2. 在上面的包中新建一个python文件(用于存放自定义filter的文件),里面定义函数,并且注册到django的模板语言

                    from django import template

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

                    register = template.Library()

     

                    @register.filter(name="sb")

                    def add_sb(value):

                        return "{} sb".format(value)

     

                   @register.filter(name="add")

                    def add(value, arg):

                        return "{} {}".format(value, arg)

     

                3. 使用自定义的filter方法  #在html中

                    {% load py文件名%}

                    {{ value|sb }}

                    {{ name|add:"super dsb" }}

     

        4. truncatechars

           {{ value|truncatechars:9}}  # 显示6个原文字符+三个. ;如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。

     

        5. Tags  #和Filters相比,Tags功能更丰富,支持逻辑等

     

            # for

            <ul>

            {% for user in user_list %}

                <li>{{ user.name }}</li>

            {% endfor %}

            </ul>

     

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

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

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

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

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

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

            forloop.parentloop      本层循环的外层循环

     

            {% empty %}

     

            # if,elif,else

            {% if user_list %}

              用户人数:{{ user_list|length }}

            {% elif black_list %}

              黑名单数:{{ black_list|length }}

            {% else %}

              没有用户

            {% endif %}

     

            if语句支持and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

     

            # with (定义一个中间变量;取别名)

            {% with total=business.employees.count %}

                {{ total }} employee{{ total|pluralize }}

            {% endwith %}

     

        6. 注意事项

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

              {% if a > b > c %}

                ...

              {% endif %}

     

              #python支持连续判断,但如果用Django模板,则不能使用连续判断

     

               若a=10, b=20, c=-5, 判断a>b>c的布尔值

               python: False; a>b and b>c -> False

               HTML: True; a>b ->False, False>-5 => 0>-5 -> True

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

              def xx(request):

                  d = {"a": 1, "b": 2, "c": 3, "items": "100"}

                  return render(request, "xx.html", {"data": d})

     

              {{ data.items }  # 默认会取d的items key的值。

     

        7. 母版与继承

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

     

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

     

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

               # 继承语句要放在子模板的最上方

     

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

               {% extends 'base.html '%}

               {% block page-main %}

                  <p>世情薄</p>

                  <p>人情恶</p>

                  <p>雨送黄昏花易落</p>

                {% endblock %}

     

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

     

            #base.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 %}  # 某些子页面单独用的css可置于此

     

              {% endblock %}

     

            </head>

            <body>

     

            <h1>这是母板的标题</h1>

            {% block page-main %}

     

            {% endblock %}

            <h1>母板底部内容</h1>

     

            {% block page-js %}

     

            {% endblock %}

     

            </body>

            </html>

     

        8.组件

            把功能相对独立的html代码(导航条,页尾信息等)放在一个单独的文件中 作为组件 供其他页面使用

            {% include 'nav.html' %} # 放在body里

            # 以nav.html为例,只放<nav>...</nav>即可

     

        #补充

    一般brower会自动帮忙加载缓存,但当开发时,不希望缓存干扰测试结果,可在检查页面做如下设置

  • 相关阅读:
    Yii2与layuiadmin整合1
    Yii2与layuiadmin整合3
    laravel8.5与layuiadmin整合(8)
    laravel8.5与layuiadmin整合(12)
    laravel8.5与layuiadmin整合(9)
    laravel8.5与layuiadmin整合(14)
    Spring Data JDBC笔记
    Spring Boot笔记 #08# DEBUG级别启动日志译成中文
    Spring Web MVC 1.3. Annotated Controllers
    Java连接数据库 #08# 一个小结(JDBC & 连接池 & ORM & JPA)
  • 原文地址:https://www.cnblogs.com/zhangyaqian/p/py20180615.html
Copyright © 2020-2023  润新知