• Django总结一


    HTTPRequest与HTTPresponse
    
    一、
    
    1、互联网两台机器之间通行:ip、端口、协议
        - 协议
            - HTTP  (80- HTTPS  (443) 
    
    2、浏览器输入URL一回车返回页面发生了什么?
        - 域名 -> DNS解析 -->ip地址 -> 找到服务端 ->服务端返回消息 -> 浏览器
        - 浏览器 <-> 服务器
        - 服务器把 写好的HTML页面,返回给浏览器,浏览器按照HTML格式渲染
        「
    
        」
    
    3、请求和相应
        - HTTP协议的特点:
            - 浏览器给服务端发消息的过程叫请求(request)
            - 服务器给浏览器回复消息的过程叫响应(response)
            
        - 请求和相应的消息都必须遵循一个固定的格式
    
    4、python中Web框架分类
        - a、收发socket消息,按照HTTP协议解析消息   Web服务程序 wsgiref(模块)、gunicorn、uWSGI
        - b、字符串替换,用来实现动态网页                                
        - c、业务逻辑处理                            Web应用程序
    
        1- 自己实现abc的
            - Tronado  
        2- 自己实现bc使用别人的a
            - Django
        3- 自己实现c使用别人的ab
            - Flask
    5、Web服务程序  <-  WSGI协议  -> Web应用程序
    
    
    5.5、Django版本
        - LTS版本 (Long Team support)
    
    6、创建第一个Django项目
        
        安装:  pip install django==1.11.11
                pip install django==1.11.11 -i 指定源 
    
        - 1、命令行  Django-admin startproject first_Django
        - 2、Pycharm创建
            - file -> new Project ->右侧选Django -> 选好路径 ->选好环境 -> 名字app -> 在新的窗口打开文件
        - 3、启动项目
            - 命令行启动(切换到项目的根目录)
                - python manage.py runserver 127.0.0.1:8090(改端口这样指定)
            - pycharm启动
                - 框中选项为项目名->让后点击启动按钮(右上角)(如果想改就在旁边点编辑-就可以改端口等)
    
        - 目录介绍
            - 和项目名一样的是根目录
            - 
        ---------------------
        - 先来一份自己的理解
            - 1、(与我们所创建文件名一致的目录)根目录
                - manage.py 
                    - 这是启动文件,程序入口。
                - settings.py
                    - 包含了项目的一些设置,包括数据库信息、调试标志以及其他的一些工作的变量。
                    - BASE_DIR = 项目的根目录
                    - TIMELATES = templates去哪找
                    - DATABASES = 数据库
                    - 静态文件配置
                        - STATIC_URL = '/static/' # 请别名
                        - STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),] # 配置去static下找静态文件
                - urls.py
                    - 路径与视图函数的映射关系
    
    
            - 2、templates - 这个文件夹存放的是HTML文件
            - 3、static - 这个文件夹是存放静态文件,需要自己配置,用的时候的导入时用 
                 /static/.. 来引入所用的静态文件
                     # Static files (CSS, JavaScript, Images)
                    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
                    # 这个static就代表了下面的路径 (寻找的时候就是去static下面的路径中挨个找)
                    STATIC_URL = '/static/'  # 起别名, HTML中找静态文件都要以这个别名开始  (找到别名后就去这个别名的配置比文件中找对应的文件)
    
                    # 这个常量是固定格式
                    STATICFILES_DIRS = [
                        os.path.join(BASE_DIR, 'static'),
                    ]
        
    7、项目流程
        - 先输入url
        - 去Django的urls中匹配urlpatterns->匹配上调用后面匹配的函数->去找对应的函数
        - 找到执行的函数->Django调用要执行的函数给函数传一个request参数,所有和请求相关的数据 都在request中
        - render去templates文件夹找到HTML文件,打开读取内容,按照http响应格式给浏览器返回读取的内容
        - 浏览器收到Django返回的响应消息,按照HTML格式显示这个消息
    
    
    
    其他:
        - from django.shortcuts import HttpResponse, render
            - HttpResponse (封装了协议头等-有待商议)
            - render (渲染)
    
        - 文件的上传(form表单的提交, 必须用POST)
            def index(request):
                print(request.GET)
                print(request.POST)
                print(request.FILES)
    
                for item in request.FILES:
                    fileobj = request.FILES.get(item)
                    f = open('upload/%s' % fileobj.name, 'wb')
                    item_file = fileobj.chunks()
                    for line in item_file:
                        f.write(line)
                    f.close()
    
                return HttpResponse("成功")
         - form表单上传文件时需要注意的事情
             - action 最后加 /  或者 修改settings:APPEND_SLASH=False
             - method 必须为post 
             - enctype = “multipart/form-data” 必须写
    
         - 指定IP登录
             默认IP和端口
                python manage.py runserver
            指定端口:
                python manage.py runserver 192.168.12.12:8080
            此时会报错,我们需要修改配置文件:
            修改settings.py,将192.168.12.12添加到ALLOWED_HOSTS中
            ALLOWED_HOSTS=['172.31.169.182','127.0.0.1','192.168.1.50','192.168.1.115']
            也可以将ALLOWED_HOSTS改成通配符 *
            ALLOWED_HOSTS = ["*"]
    
    
    
    二、
    
    1、表单的提交(登录)
        - submit -> action -> 对应函数(参数request(数据信息))-> 处理
            注意:必须要有name属性 *****
        - 提交到服务器的是QueryDict对象,可以通过get获取值
    
    
    2、form表单提交的三个要素
        - form标签必须有action和method属性
        - 所有获取用户输入的标签必须放在form表单中,必须有name属性(input,select,textarea)
        - 必须有submit按钮
    
    
    3、redirect 跳转,改变方向
        - 跳转到别人的页面,自己的页面
            - 跳转比人页面
                redirect("https://baidu.com")
            - 跳转自己页面
                redirect("/相对路径/")
    
    4、Django必会三件套  from django.shortcuts import
        - HttpRequest    返回一个指定的字符串    
            (把字符串转为而二进制,然后按照HTTP响应格式要求返回)
        - render           返回一个HTML文件        HTML文件 模板语言
            (第一个参数为request, 第二个参数为render的页面,第三个参数为字典,将render页面中的特殊符号替换{字典的键为html的变量,值为给页面展示的值})
        - redirect        跳转           路径     URL
            (redirect(/index/) -> 在同网站不同地址间跳转(返回重定向响应)
              redirect('https://wwww.baidu.com') -> 访问指定的网址)
    
    5、request相关属性 (所有和请求相关的数据都封装在request对象中)
        - POST      取到POST提交的数据(form表单提交的)
        - GET         取到URL携带的参数
        - method    当前这次请求的方法(GET/POST)
    
    6、Django的模板语言
        {{ 变量 }}
    
    7、Django项目project
        - app(应用) -> 不同的功能放在不同的app中
            - 命令 :
                - 创建app  
                    python manage.py startapp app01(应用名)    
                - 注册app(告诉Django创建了app)
                    在settings中的 INSTALLED_APPS 添加新创建的app(app名.apps.apps中的类)
    
    
    8、程序链接mysql
        - 使用pymysql模块
            - 导入pymysql
            - 创建链接
            - 获取执行命令的游标
            - 用游标执行SQL语句
            - 获取SQL语句的执行结果
            - 关闭游标
            - 关闭链接
    
        - ORM - Object Relationship Mapping (对象关系映射)
        - 这时,创建一种工具 帮助我们翻译SQL语句(ORM - 面向对象的思想)
            - 优点
                - 开发效率高
                - 开发不用直接写SQL语句
            - 缺点
                - 执行效率低
    
        - 对应关系
            ORM         DB
    
            类            数据表
            属性            字段
            对象            数据行
    
    
    
        - Django项目project
            - app(应用) -> 不同的功能放在不同的app中
                - 命令 :
                    - 创建app  
                        python manage.py startapp app01(应用名)    
                    - 告诉Django创建了app
                        在settings中的 INSTALLED_APPS 添加新创建的app(app名.apps.apps中的类)
        - Django中ORM使用
            - 用处:
                - 操作数据表
                - 操作数据行
            - 使用
                - 手动创建数据库
                - 告诉Django连那个数据库
                    - settings中配置DATABASES
                    DATABASES = {
                        'default': {
                            'ENGINE': 'django.db.backends.mysql',  # 链接数据库的类型
                            'NAME': 'db',  # 链接数据库的名字
                            'HOST': '127.0.0.1',  # 数据库主机地址
                            'PORT': 3306,  # 数据库端口
                            'USER': 'root',  # 数据库用户名
                            'PASSWORD': '123456',  # 数据库密码
                        }
                    }
    
                - 用什么链接数据库?
                    - 利用第三方包 pymysql 和 MySQLdb(py2中)
                    - 告诉Django用pymysql模块代替默认的MySQLdb链接MySQL数据库
                        和settings.py同级的__init__.py文件,写上
                        import pymysql
                        pymysql.install_as_MySQLdb()
    
                - 在app/models.py的文件中创建类
                    类必须继承models.Model
    
    
                - 两个命令
                    - python manage.py makemigrations -> 生成脚本文件存放在app文件夹应用下的migrations文件夹中(相当于拿个小本本把models.py的变更记录下来)
                    - python manage.py migrate -> 把上面的变更记录翻译成sql语句,去数据库执行
    
                - ORM查询
                    modules.User.object.filter(email='', pwd='')
    
    
    三、
    
    1、图书管理系统
        - 出版社
            id name
        - 作者
            id name
        - 书
            id title 出版社_id
        - 书_作者关系表
            id 书_id 作者_id
    
    2.ORM增删改查
        models.表名.object./filter()/all()/create()
            - filter()  按照指定内容筛选 (字段=值)                放回一个列表
            - all()        查询出数据库所有信息(属性order_by(id)排序) 返回一个列表
            - create()    向数据库添加信息 (字段=值)创建一个对象        返回一个创建的对象
            - get()        返回一个对象
            - filter(id='').delete()    删除
            - obj = 类名.object.get(id='')
                obj.name = '新值'     修改对象的属性(修改数据行某个字段的值)
                obj.save()            把修改同步到数据库
    
    3、模板语言
        - for循环
            {% for i in ret %}
                {{ i }}
                {{ forloop.counter }}      for循环从1开始计数
                {{ forloop.counter0 }}    for循环从0开始计数
            {% endfor %}
    
    
    总结:ORM的 查、增、删、改
    
        -- client
                - 有一个展示页面(xxx_show.html)
                    - 这一个页面一输入执行后,get请求向server端发送
                - 这个展示页面有添加按钮、删除按钮、编辑按钮
                - 这个页面要展示内容
                    - 是server端收到第一次的get请求而做出的response
                    - 页面需要用到模板语言for循环
                        {% for i in result %}
                            {{ i.xx }}  #获取result中的每个值(也就是server端传来的东西) 
                        {% endfor %}
            - server
                - 首先会收到一开始访问页面的GET请求
                - 收到请求后到urls中找匹配的url,找到对应的url后,执行后面所对应的视图函数
                - 找到对应的视图函数后就行执行响应的逻辑,也就是拿出数据库中的东西,发送给server
                    - 可以通过 models.表名.objects.all() 获取数据库这张表中的所有内容(返回一个列表)
                        - data = models.表名.objects.all()
                    - 拿到数据后将这些数据给展示(通过render方法)
                        - return render(request, 'xxx_show.html', 'result':data)
                         #这里的result就是要传给xxx_show.html的一个变量(其中的值就是data的数据)
    
        -- client
                - 有一个展示页面(xxx_show.html)
                - 这个页面有一个添加按钮(a标签)
                    - 点击这个按钮(a标签),client会发送一个get请求,会用a标签的路径去访问server
                    - 这时会跳转到a标签所指的url(/add_xxx/)
                    - 然后server给出response(这里的业务逻辑就都得在server)
                - 第一次get请求server会返回一个add_xxx.html页面
                    - 这是可以添加数据
                        - 用form表单,action为add_xxx这个url,method为post
                        - 点击提交之后client向server发送一个请求
                        - server收到请求后回复一个response
    
            - server
                - 收到a标签跳转的url(get请求响应)
                - 收到add_xxx这个url进入urls中匹配,匹配到就去他对应的视图函数
                - 这个视图函数处理响应的业务逻辑
                    - 首先第一次来的时候时GET请求,这个时候应该将add_xxx.html这个页面返回给client
                        - return render(request, add_xxx.html)
                    - 然后server收到提交的POST请求
                        - 从POST请求中拿出client发送来的数据
                            - data = request.POST.get("input标签的name")
                        - 将数据存入数据库
                            - models.tablename.objects.create(字段=data)
                        - 将数据库中的结果重新返回(也就是xxx_show。html)
                            - return redirect('/xxx_show/')
    
        -- client
                - 有一个展示页面(xxx_show.html)
                - 有一个删除按钮(a标签)
                    - 点击这个按钮(a标签),client会发送一个get请求,会用a标签的路径去访问server
                    - 点击这个a标签(按钮)会跳转到他对应的url('/del_xxx/')
                        - 这时需要将这个按钮对应的数据传到server,server才能按照这个数据去删除
                        - <a href="/del_xxx/?id={{ i.id }}"><button>del</button></a>
                            - ?是一个固定格式,而后面就是一些参数(服务端要用的一些参数)
                            - server收到这个参数后就可以按照他进行相应的操作
                    - 然后server会返回一个response(这里的业务逻辑在server端)
    
            - server
                - 收到a标签跳转的url(get请求响应)
                - 收到del_xxx这个url进入urls中匹配,匹配到就去他对应的视图函数
                - 这个视图函数处理响应的业务逻辑
                    - 通过client传来的参数来锁定删除的id
                        - del_id = request.GET.get("id")
                    - 删除数据库中del_id对应的值
                        - models.tablename.objects.fileter(id=del_id).delete()
                    - 删除成功后返回删除后的页面('/xxx_show/')(重定性)
                        - return redirect('/xxx_show/')
    
        -- client
                - 有一个展示页面(xxx_show.html)
                - 有一个编辑(edit)按钮(a标签)
                    - 点击这个按钮(a标签),client会发送一个get请求,会用a标签的路径去访问server
                    - 点击这个a标签(按钮)会跳转到他对应的url('/edit_xxx/')
                        - 这时需要将这个按钮对应的数据传到server,server才能更改这个数据
                        - <a href="/edit_xxx/?id={{ i.id }}"><button>del</button></a>
                            - ?是一个固定格式,而后面就是一些参数(服务端要用的一些参数)
                            - server收到这个参数后就可以按照他进行相应的操作
                    - 然后server会返回一个response(这里的业务逻辑在server端)
                - 第一次发送get请求时会跳转到edit_xxx.html这个页面,这里面是该行对应的数据
                - 第二次发送post请求,这里面会有修改后的数据然后发送给server处理
                    -     <form action="/edit_press/?id={{ result.id }}" method="post">
                            <input type="text" name="updata_name" value="{{ result.name }}">
                            <input type="submit">
                        </form>
    
                        - input中的数据都是在server查出的数据展现出来的
                        - id是通过点击edit按钮的时候将这个按钮对应的id值记录了下来
    
                    - 处理完后返回原来的xxx_show
    
    
            - server
                - 收到a标签跳转的url(get请求响应)
                - 收到edit_xxx这个url进入urls中匹配,匹配到就去他对应的视图函数
                - 这个视图函数处理响应的业务逻辑
                    - 第一遍的GET请求
                        - 通过client传来的参数来锁定编辑(edit)的id
                            - edit_id = request.GET.get("id")
                        - 会返回当前编辑行的内容
                            - 从数据库中拿出这个值,将这个值展现在edit_xxx.html页面中
                                - result = models.tablename.objects.filter(id="")[0]
                        - 返回当前编辑的页面
                            - return render(request, 'edit_xxx.html', {'resule': result})
    
                    - 第二遍请求是提交数据后的POST请求,
                        - form表单中的action为这个编辑页面,
                        - 这个页面后面的参数为第一次get请求得到的数据
                        - 可以通过GET方法来获取URL上的参数的值
    
                        - 这个时候form表单对应的url来urls中找对应的视图函数
                            - 这个视图函数就会执行POST请求的逻辑
                            - 用这个新数据把数据库中的旧数据掩盖
                                - 获取更改后的值
                                    - data = request.POST.get("updata_name")
                                - 更改数据库中的值
                                    - 从数据库找到id对应的对象
                                    - #这里的id就是第一次点击编辑的时候得到的id值(--对应的)
                                    - new_obj = models.tablename.objects.filter(id='edit_id')[0]
                                    - new_obj.name = data  #将新的值赋值给数据库中的变量
                                    - new_obj.save()  #这个事务必须save数据库中的数据才会更改
    
                                - 更改完成后返回,xxx_show页面
                                    - return redirect('/xxx_show/')
    
    
    
        注意:
            通过GET来获取URL中的值(和请求无关),POST获取表单提交的值。
    
    
    
    
    四、
    
    1、 a标签
        - href属性
            - 相对路径
            - 绝对路径
        - target = "_blank" 跳转到新页面, 不写默认覆盖自己的页面
        - 锚点(同网站标签的跳转(#id名))
    
    2# 出版社
    class Press(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
    
        def __str__(self):  # print的时候测试使用
            return self.name
    
    
    #
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        # Django1.1默认就是级联删除,2.0必须指定
        # 可以通过字符串的反射找Press,如果在代码前面就可以直接用,to=关联的表名
        # 外键字段ORM会给他默认加一个_id (加上_id后他的值就是对应关联表的主键值)
        press = models.ForeignKey(to='Press', on_delete=models.CASCADE)
        
    
    - 一对多
        - 一个出版社对应多本书(外键设置在多的一方)
            - 书的属性有一个外键为链接出版社的press_id
    
    书籍的增删改查
        ---- 查
    
    注意:
        - 增的时候,出版社就是表中的固定出版社,用一个select标签将数据展示,而不是用户自己填
            <form action="/add_book/" method="post">
              书名:<input type="text" name="book_title">
              <select name="title_name" id="">
                {% for press in data %}
                    <option value="{{ press.id }}">
                        {{ press.name }}
                    </option>
                {% endfor %}
              </select>
              <input type="submit">
           </form>
        - 改的实时,出版社的内容需要先选定好。需要用模板语言来判断
            # 这中情况form表单不指定action他默认会提交当前的页面(这是的页面是点击编辑时的页面)
            <form action="/edit_book/?id={{ data.id }}" method="post">
                <input type="text" name="title_name" value="{{ data.title }}">
                <select name="press_name" id="">
                    {% for press in data_list %}
                        {% if data.press == press %}
                            <option value="{{ press.id }}" selected>
                            </option>
                                {{ press.name }}
                            {% else %}
                            <option value="{{ press.id }}">
                                {{ press.name }}
                            </option>
                        {% endif %}
                    {% endfor %}
                </select>
                <input type="submit">
            </form>
    
    
    五、
        - 给数据库中已经存在的表添加另外一个字段,ORM不知道如何处理
            - 1) 输入 1 会让用户自己填写一个默认值(在命令行中)
            - 2) 输入 2 自己在ORMclass中指定字段自己加默认值(退出命令行)在modules中修改
                    - null = True
                    - default = 默认值
    
    
    1. 多对多关系    
            作者   <-->  书籍
            1. 表结构设计
                1. SQL版
                    -- 创建作者表
                    create table author(
                        id int primary key auto_increment,
                        name varchar(32) not null
                    );
                    
                    -- 创建作者和书的关系表
                    create table author2book(
                        id int primary key auto_increment,
                        author_id int not null,
                        book_id int not null,
                        constraint fk_author foreign key (author_id) references author(id) on delete cascade on update cascade,
                        constraint fk_book foreign key (book_id) references book(id) on delete cascade on update cascade
                    );
    
                2. ORM版
                    1. 第一版:
                        自己创建第三张表
                    2. 第二版
                        让ORM帮我们创建第三张表
                        models.ManyToManyField()
                    3. 第三版
                        待补充...(ORM进阶操作的时候)            
        2. 作者的增删改查
            1. 查询
                author_obj.books        --> 得到的只是一个关联关系,并不能拿到数据
                author_obj.books.all()  --> 得到和我这个作者关联的所有书籍对象列表
            2. 添加
                1. getlist() # 得到同一name的列表对象
                2. add()
                3. set()
                
            3. 删除
            
            4. 编辑
                1. 模板语言中
                    {% if book in author.books.all %}
                2. ORM编辑多对多
                    1. 不能直接操作第三张关系表
                    2. 借助ORM给提供的方法
                        1. all()
                        2. add(id1,id2)
                        3. set([id1, id2])
                        4. clear()
        3. Django模板语言
            1. for循环
                1. forloop.last
                    {% if forloop.last %}
                        ...
                2. empty
                    {% for i in x %}
                        ...
                    {% empty %}
                        ...
                    {% endfor %}
        4. 上传文件
            form表单上传文件
            # 文件的上传
            def index(request):
                print(request.FILES)  # 上传的文件列表对象
                for item in request.FILES:
                    fileobj = request.FILES.get(item)  # 挨个获取列表中每个对象
                    f = open('upload/%s' % fileobj.name, 'wb')
                    item_file = fileobj.chunks()
                    for line in item_file:
                        f.write(line)
                    f.close()
    
                return HttpResponse("成功")
    
    2. 学生管理系统
        - 老师 和 班级 是多对多的关系
    
    
    
    
    六、Django模板系统(模板语言)(very important)
        - 基础语法
            - 跟变量相关 {{ }}
                在Django的模板语言中按此语法使用:{{ 变量名 }}。
    
                当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。 
                变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。
                点(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询:
    
                ***** 属性->方法->索引
                字典查询(Dictionary lookup)
                属性或方法查询(Attribute or method lookup)
                数字索引查询(Numeric index lookup)
    
                注意事项:
    
                如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
                如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为'' (空字符串) 。
                
                {# 取l中的第一个参数 #}
                {{ l.0 }}
                {# 取字典中key的值 #}
                {{ d.name }}
                {# 取对象的name属性 #}
                {{ person_list.0.name }}
                {# .操作只能调用不带参数的方法 #}
                {{ person_list.0.dream }}
    
                - Filter过滤器
                    在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
                    过滤器的语法: {{ value|filter_name:参数 }}
    
                    使用管道符"|"来应用过滤器。
    
                    例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。
    
                    注意事项:
    
                    过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
                    过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
                    过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
                    '|'左右 没有空格没有空格没有空格   ******
                     
                    Django的模板语言中提供了大约六十个内置过滤器
    
                    - 一些常用的过滤器
                        - default
                            如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
    
                            {{ value|default:"nothing"}}
                            如果value没有传值或者值为空的话就显示nothing
                            注:TEMPLATES的OPTIONS可以增加一个选项:string_if_invalid:'找不到',可以替代default的的作用。
    
                        - length
                            返回值的长度,作用于字符串和列表。
    
                            {{ value|length }}
                            返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.
    
                        - filesizeformat
                            将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:
    
                            {{ value|filesizeformat }}
                            如果 value 是 1234567890,输出将会是 1.1GB。
    
                        - slice
                            切片
    
                            {{value|slice:"2:-1"}}
                        - add
                            给变量加参数
    
                            {{ value|add:"2" }}
                            value是数字4,则输出结果为6。
    
                            {{ first|add:second }}
                            如果first是 [1,.2,3] ,second是 [4,5,6] ,那输出结果是 [1,2,3,4,5,6] 。
    
                        - data
                            格式化
    
                            {{ value|date:"Y-m-d H:i:s"}}
                            可用的参数:
                                格式化字符    描述            示例输出
                                    a    'a.m.''p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间)    'a.m.'
                                    A    'AM''PM''AM'
                                    b    月,文字,3个字母,小写。    'jan'
                                    B    未实现。     
                                    c    ISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。    2008-01-02T10:30:00.000123+02:00或2008-01-02T10:30:00.000123如果datetime是天真的
                                    d    月的日子,带前导零的2位数字。    '01''31'
                                    D    一周中的文字,3个字母。    “星期五”
                                    e    时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。    '''GMT''-500''US/Eastern'等
                                    E    月份,特定地区的替代表示通常用于长日期表示。    'listopada'(对于波兰语区域,而不是'Listopad')
                                    f    时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。    '1''1:30'
                                    F    月,文,长。    '一月'
                                    g    小时,12小时格式,无前导零。    '1''12'
                                    G    小时,24小时格式,无前导零。    '0''23'
                                    h    小时,12小时格式。    '01''12'
                                    H    小时,24小时格式。    '00''23'
                                    i    分钟。    '00''59'
                                    I    夏令时间,无论是否生效。    '1''0'
                                    j    没有前导零的月份的日子。    '1''31'
                                    l    星期几,文字长。    '星期五'
                                    L    布尔值是否是一个闰年。    True或False
                                    m    月,2位数字带前导零。    '01''12'
                                    M    月,文字,3个字母。    “扬”
                                    n    月无前导零。    '1''12'
                                    N    美联社风格的月份缩写。 专有扩展。    'Jan.''Feb.''March''May'
                                    o    ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。    '1999年'
                                    O    与格林威治时间的差异在几小时内。    '+0200'
                                    P    时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串“午夜”和“中午”。 专有扩展。    '1 am''1:30 pm' / t3>,'midnight''noon''12:30 pm' / T10>
                                    r    RFC 5322格式化日期。    'Thu, 21 Dec 2000 16:01:07 +0200'
                                    s    秒,带前导零的2位数字。    '00''59'
                                    S    一个月的英文序数后缀,2个字符。    'st''nd''rd''th'
                                    t    给定月份的天数。    28 to 31
                                    T    本机的时区。    'EST''MDT'
                                    u    微秒。    000000 to 999999
                                    U    自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。     
                                    w    星期几,数字无前导零。    '0'(星期日)至'6'(星期六)
                                    W    ISO-8601周数,周数从星期一开始。    1,53
                                    y    年份,2位数字。    '99'
                                    Y    年,4位数。    '1999年'
                                    z    一年中的日子    0到365
                                    Z    时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。    -43200到43200
    
    
                        - safe
                            Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。
                            但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的
                            文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,
                            如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有
                            两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安
                            全的不必转义。
    
                            比如:
    
                            value = "<a href='#'>点我</a>"
                            {{ value|safe}}
    
    
                        - truncchars
                            如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
    
                            参数:截断的字符数
    
                            {{ value|truncatechars:9}}
    
                        - truncatewords
                            在一定数量的字后截断字符串。
    
                            {{ value|truncatewords:9}}
    
                        - cut
                            移除value中所有的与给出的变量相同的字符串
    
                            {{ value|cut:' ' }}
                            如果value为'i love you',那么将输出'iloveyou'.
    
                        - join
                            使用字符串连接列表,例如Python的str.join(list)
    
                        - timesince
                            将日期格式设为自该日期起的时间(例如,“4天,6小时”)。
    
                            采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。
                            例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:
    
                            {{ blog_date|timesince:comment_date }}
                            分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。 
    
                        - timeuntil
                            似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。 
                            例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。
    
                            使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”:
    
                            {{ conference_date|timeuntil:from_date }}
    
    
                    - 自定义filter
                        - 自定义过滤器只是带有一个或两个参数的Python函数:
    
                            变量(输入)的值 - -不一定是一个字符串
                            参数的值 - 这可以有一个默认值,或完全省略
                            例如,在过滤器{{var | foo:'bar'}}中,过滤器foo将传递变量var和参数“bar”。
    
    
                        - 创建 (步骤)
                            - 先在app目录下创建一个templatetagspython包(名字必须这个)
                            - 在目录中创建一个py文件
                            - 在py文件中按照固定的格式自定义一个filter(就是一个函数)
                            - 需要先导入 from django import template 
                                # 固定写法,生成一个注册实例对象
                                register = template.Library()
    
                                @register.filter()  # 告诉Django的模板语言我现在注册一个自定义的filter
                                def add_str():pass  # 第一个参数是变量名, 第二个参数为参数(最多一个)
    
                            - 使用:
                                - 重启DJango项目
                                - 在HTML页面中:{% load python文件名 %}
                                - {{ name|add_str:'好人啊' }}
    
    
    
                        - 例子:
                            - 自定义过滤器只是带有一个或两个参数的Python函数:
    
                                变量(输入)的值 - -不一定是一个字符串
                                参数的值 - 这可以有一个默认值,或完全省略
                                例如,在过滤器{{var | foo:“bar”}}中,过滤器foo将传递变量var和参数“bar”。
    
                            - 自定义filter代码文件摆放位置:
    
                                app01/
                                    __init__.py
                                    models.py
                                    templatetags/  # 在app01下面新建一个package package
                                        __init__.py
                                        app01_filters.py  # 建一个存放自定义filter的py文件
                                    views.py
                            
                            - 编写自定义filter
    
                        
                                from django import template
                                register = template.Library()
    
    
                                @register.filter
                                def fill(value, arg):
                                    return value.replace(" ", arg)
    
    
                                @register.filter(name="addSB")
                                def add_sb(value):
                                    return "{} SB".format(value)
                            
                            - 使用自定义filter
    
                                {# 先导入我们自定义filter那个文件 #}
                                {% load app01_filters %}
    
                                {# 使用我们自定义的filter #}
                                {{ somevariable|fill:"__" }}
                                {{ d.name|addSB }}
    
                        - 注意:过滤器可以链接
                            {{ text|escape|linebreaks }} 就是一个常用的过滤器链,它编码文本内容,然后把行打破转成<p> 标签。
    
    
            - 跟逻辑相关 {% %}
                - 语法为:{% tag %}
    
                - 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    本层循环的外层循环(是个字典)
    
                    forloop是一个字典
    
                    - for ... empty
                        <ul>
                        {% for user in user_list %}
                            <li>{{ user.name }}</li>
                        {% empty %}
                            <li>空空如也</li>
                        {% endfor %}
                        </ul>
                
                - if,elif和else
    
                    {% if user_list %}
                      用户人数:{{ user_list|length }}
                    {% elif black_list %}
                      黑名单数:{{ black_list|length }}
                    {% else %}
                      没有用户
                    {% endif %}
                    
                    当然也可以只有if和else
    
                    {% if user_list|length > 5 %}
                      七座豪华SUV
                    {% else %}
                        黄包车
                    {% endif %}
                    
                    注:
                        - if语句支持 andor、==、>、<、!=、<=、>=、innot inisis not判断。
    
    
                - with    (就相当于起了一个别名)
                    -     {% with p1.dream as dream %}
                            {{ dream }}   # dream 代替p1.dream
                        {% endwith %}
                    - 定义一个中间变量
                        {% with total=business.employees.count %}
                            {{ total }} employee{{ total|pluralize }}
                        {% endwith %}
    
                - csrf_token
                    - 这个标签用于跨站请求伪造保护。
                    - 在页面的form表单里面写上{% csrf_token %}
                        - 用这个后就可以将中间件打开(这样就安全了,知道是我能够收取的)
                        - 在表单中添加了一个隐藏的input标签
                            - name csrfmiddlewaretoken
                            - value asksdasdas(64位)
                - # 注释
                    - {# ... #}
    
                - 母版(一个普通的html文件) block extends
                    - 减少代码的重复
    
                    - 母版写好
                        - 不同的地方用以下占位
                        - {{ block contenter(name) }}
    
                            {{ endblock }}
                    - 子文件
                        - {% extends '母版html' %}  # 继承母版
    
                        - {% block contenter(name) %}  # 将母版中的站好位置额contenter填充
                                自己的html文件
                            {% endblock %}
    
                    - 注意事项:
                        - {% extends '母版html' %}  # 继承母版  必须写在开头
                        - {% extends name %}  name写继承的模板的名字字符串
                        - 自定义的内容写在block中
                        - 定义多个block块,一般要有js css
    
    
                - 注意事项
                    - Django的模板语言不支持连续判断,即不支持以下写法:
                        {% if a > b > c %}
                        ...
                        {% endif %}
                    - Dja的模板语言中属性的优先级大于方法
                        def xx(request):
                            d = {"a": 1, "b": 2, "c": 3, "items": "100"}
                            return render(request, "xx.html", {"data": d})
                         如上我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 
                         方法,此时在模板语言中:
    
                        {{ data.items }}
                        默认会取d的items key的值。
    
    
                - 组件 include
                    - 可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。
                        {% include 'navbar.html' %}
    
                - 静态文件相关(动态拿取STATIC_URL配置的名字)
                    - 
                        {% load static %}
                        <img src="{% static "images/hi.jpg" %}" alt="Hi!" />
                        
                        引用JS文件时使用:
                        {% load static %}
                        <script src="{% static "mytest.js" %}"></script>
                        
                        某个文件多处被用到可以存为一个变量
                        {% load static %}
                        {% static "images/hi.jpg" as myphoto %}
                        <img src="{{ myphoto }}"></img>
    
                    - get_static_prefix
                        {% load static %}
                        <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
                        
                        或者
                        {% load static %}
                        {% get_static_prefix as STATIC_PREFIX %}
    
                        <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
                        <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />
    
                - 自定义simpletag
                    和自定义filter类似,只不过接收更灵活的参数。
    
                    定义注册simple tag
                    @register.simple_tag
    
                    @register.simple_tag(name="plus")
                    def plus(a, b, c):
                        return "{} + {} + {}".format(a, b, c)
    
                    使用自定义simple tag
                    {% load app01_demo %}
    
                    {# simple tag #}
                    {% plus "1" "2" "abc" %}
    
                - inclusion_tag
                    - 多用于返回html代码片段
    
                    - 步骤
                        - 在app下创建templatetags的python包
                        - 在包下写py文件 mytags
                        - 编辑文件
                            - from django import template
                            - register = template.Library()
    
                        - 定义函数
                            - 可接受参数
                            - 返回一个字典
                        - 函数加装饰器
                            - @register.inclusion_tag('result.html')
    
                    示例:
    
                        templatetags/my_inclusion.py
    
                        
                            from django import template
    
                            register = template.Library()
    
    
                            @register.inclusion_tag('result.html')
                            def show_results(n):
                                n = 1 if n < 1 else int(n)
                                data = ["第{}项".format(i) for i in range(1, n+1)]
                                return {"data": data}
                    
                        templates/result.html
    
                            <ul>
                              {% for choice in data %}
                                <li>{{ choice }}</li>
                              {% endfor %}
                            </ul>
                        
                        templates/index.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>inclusion_tag test</title>
                            </head>
                            <body>
    
                            {% load my_inclusion %}
    
                            {% show_results 10 %}
                            </body>
                            </html>
     
    
    
    
    - 细节
        input data属性 value='是一个“-”链接的字符串'
  • 相关阅读:
    东南大学2020年数学分析考研试题参考解答
    东北师范大学2020年数学分析考研试题参考解答
    丁同仁常微分方程第一版习题参考解答
    电子科技大学2020年数学分析考研试题参考解答
    点集拓扑课件/作业/作业讲解
    毕业论文[博士]不可压缩流体动力学方程组的若干正则性条件
    毕业论文[本科]笛卡尔积上的拓扑学
    Ibragimov微分方程与数学物理问题习题参考解答
    Evans Partial Differential Equations 第一版第1-3章笔记及习题解答
    [Tex模板]Annales Polonici Mathematici
  • 原文地址:https://www.cnblogs.com/xiao-xue-di/p/9729245.html
Copyright © 2020-2023  润新知