• django


    Django 框架

    Django 框架
    1、WEB 与 服务器
    1、WEB :表示用户可以浏览的网页内容(HTML,CSS,JS)
    2、服务器
    能够给用户提供服务的机器
    1、硬件 与 软件
    硬件范畴:一台机器
    软件范畴:一个能够接收用户请求并给出相应的程序
    1、APACHE
    2、TOMCAT
    3、IIS
    4、Nginx
    2、作用
    1、存储WEB所需要的信息(HTML,图片,音频,...)
    2、能够处理用户的请求(request),并给出响应(response)
    3、执行服务器端的程序 :查找数据库

    3、服务器 与 WEB之间的关系

    4、Django 框架
    1、作用
    使用 python 语言开发服务器端处理程序
    2、框架
    1、什么是框架
    框架是一个为了解决开放性问题而存在的一种结构。框架本身提供一些最基本的功能。
    我们只需要在基础功能上搭建属于自己的操作即可。
    2、Python 中的框架
    1、Django :重量级的 WEB 框架
    2、Tornado :异步框架
    3、Flask :轻量级框架
    ... ...
    3、Django 框架
    1、什么是Django
    是一个开源框架,2005年发布,采用Python语言开发。早期是做新闻以及内容管理的网站的。
    提供了非常强大的后台管理系统。
    2、Django 的框架模式 - MTV
    M :Models 层
    模型层,负责数据库的建模以及CRUD的操作
    T :Templates 层
    模板层,用于处理用户显示的内容的 如:html
    V :Views 层
    视图层
    处理与用户交互的部分内容,从模型中获取数据,再将数据发送给模板,显示给用户

    自行了解:MVC
    M :Models
    V :Views
    C :Controller(控制器)
    4、Django 框架的使用
    1、Django的安装
    1、查看已安装的Django版本
    1、进入到终端 以及 Python 的交互模式
    python3 / ipython3
    2、在交互模式中 输入 import django
    如果未报错:说明已经安装过
    如果报错:说明未安装
    3、查看已安装的版本
    交互模式中:django.VERSION
    2、安装
    1、在线安装 - 使用 pip / pip3
    sudo pip3 install django
    (默认安装Django的最高版本)

    sudo pip3 install django==1.11.8
    (指定安装1.11.8版本)
    2、离线安装
    1、下载所需要的Django包
    2、在环境中解压 Django 包
    tar -xvf Django-1.11.8.tar.gz
    3、进入到 Django-1.11.8
    cd Django-1.11.8
    4、安装
    sudo python3 setup.py install

    Django官网:http://www.djangoproject.com
    Djangobook:http://djangobook.py3k.cn/2.0/

    1、创建Django项目

    1. mkdir Django -- 创建目录,用于保存项目(可选)

      使用 django-admin 指令,创建Django项目
      例: django-admin startproject 项目名

    2. 创建app

      python3 manage.py startapp app01

    3. 在settings.py  修改一些配置

      1.  将 app 加到 INSTALLED_APPS 中。

      2.  创建 temolate 文件夹,并在 TEMPLATES 的 'DIRS' 添加路径, 'DIRS':[os.path.join(BASE_DIR, 'template')]

         3.  创建  static 文件夹,并 设置 路径     

      STATICFILE_DIRS = [
      os.path.join(BASE_DIR, "static"),
      ]

    4、启动服务,用于访问
      在创建好的项目中,找到 manage.py 文件
      通过 manage.py启动项目(服务)
      python3 manage.py runserver 8899

    5、访问网站
      启动服务之后,在浏览器中,通过以下网址访问:
      http://localhost:8000
      http://127.0.0.1:8000
      http://localhost:8000/admin

    2、Django项目结构介绍

    1、manage.py
    负责执行django中的各项操作的文件
    如:
    启动服务
    创建应用
    创建管理员
    数据库的同步

    调用方式:
    1. python3 manage.py 子命令
    2。 ./manage.py 子命令

    2、主文件夹(名称与项目名称相同)
    1、__init__.py
    项目初始化文件,每当服务器启动的时候,都会自动执行
    2、urls.py
    项目的基础url(路由)配置文件
    3、wsgi.py
    应用服务器配置文件,暂时不用
    4、settings.py
    项目的主设置文件:应用,模板,数据库,语言,时区,... ...
    1、BASE_DIR : 获取当前项目的绝对路径
    2、DEBUG : 调试模式
    开发过程:推荐使用 True
    上线运行:必须改为 False
    3、ALLOWED_HOSTS
    设置允许访问本项目的地址列表。
    如果不设置的话,只有本机(localhost/127.0.0.1)能访问。
    推荐写 '*',任何表示该机器的地址都可以访问当前项目(局域网)

    或者写 python3 manage.py runserver 0.0.0.0:8888
    4、INSTALLED_APPS
    指定已安装的应用,如果有自定义的应用的话,需要在此注册
    5、MIDDLEWARE:注册中间件
    6、ROOT_URLCONF:指定项目的基础路由配置文件
    7、TEMPLATES:指定模板的信息
    8、DATABASES:指定数据库的信息
    9、LANGUAGE_CODE:指定语言,允许修改为zh-Hans
    10、TIME_ZONE:指定时区,建议改为 Asia/Shanghai

    ====================================================6.21


    4、URL的使用
    1、urls.py
    默认在主文件夹中,主路由位置文件,包含所有的地址映射。
    每一个请求到达之后,都会由urls.py中的 urlpatterns 列表中的 url() 进行匹配

    url() 函数匹配上之后,可能将请求转交给其他的 Views(视图) 或 其他的 ulrs.py 去处理
    2、测试
    1、在项目主文件夹中,创建 views.py
    作用:包含所有定义好的视图(处理程序)
    3、url函数
    url函数的语法
    url(regex,views,kwargs=None,name=None)
    1、regex
    正则表达式模板,匹配请求的 url
    2、views
    URL处理的视图函数
    3、kwargs
    字典,用来向views传参的,没有参数可以省略
    4、name
    字符串,给 url() 起别名,主要在模板中使用

    如: urlpatterns = [
    url(r'^run/$',run_views),
    ]


    4、通过 url 向 views 传参
    目的: 是为了更加精确的找到信息
    1、使用正则表达式传参
    使用子组传参,一个子组是一个参数,想传递多个参数的话,可以使用多个子组
    子组 - ()

    urlpatterns = [
    # 访问路径是 run/ 的时候,交给 run_views
    url(r'^run/$',run_views),

    # 访问路径是 fun/ 的时候,交给 fun_views
    url(r'^fun/$',fun_views),

    # 访问路径是 fun/两位数字 ,交给 fun_args_views 去处理
    url(r'^fun/(d{2})/$',fun_args_views),

    # 访问路径是 fun/四位数字/两位数字
    url(r'^fun/(d{4})/(d{2})/$',fun_args1_views)
    ]
    注意:
    1、在 url() 中,一个子组()表示一个参数
    2、在views.py中,对应的处理函数要根据url()中子组的个数,相应的定义参数。定义的参数要位于request之后

    2、使用 url() 第三个参数 ,字典传参
    在urls.py里面写
    urlpatterns = [
    url(
    r'^show/$',
    show_views,
    {'name':'zsf','age':'25'})
    ]

    在 views.py 有:
    def show_views(request,name,age):
    name 的值是 zsf
    age 的值是 25
    注意:
    1、视图处理函数中,必须声明参数
    2、参数的名称和位置,必须要与字典中的名称和位置保持一致

    5、Django 中的应用
    1、什么是应用
    应用就是网站中的一个独立的模块程序
    在Django中,主目录一般不处理用户的请求,主要做的是项目的初始化以及请求的分发

    2、创建应用
    1、命令
    ./manage.py startapp 应用名称
    ex:
    ./manage.py startapp news
    2、在 settings.py 中进行注册
    在 INSTALLED_APPS 中追加应用名称
    INSTALLED_APPS = [
    'django.contrib.admin',
    .... ....,
    'news',
    ]
    3、应用的结构组成
    1、migrations 目录
    存放数据库中间文件的目录(日志文件)
    2、__init__.py
    应用的初始化文件
    3、admin.py
    应用的后台管理配置文件
    4、apps.py
    应用的属性配置文件,不需改动
    5、models.py
    Models 文件 与数据库有关
    6、tests.py
    测试模块
    7、views.py
    定义视图的文件
    练习:
    1、创建 index 应用,并注册
    2、创建 sport 应用,并注册
    3、创建 music 应用,并注册

    作业:
    1、访问
    http://localhost:8000/sport/index
    交给 sport 应用中的 urls 处理(找index_views视图)
    2、访问
    http://localhost:8000/music/index
    交给 music 应用中的 urls 处理(找index_views视图)
    3、访问
    http://localhost:8000/
    交给 index 应用中的 urls 处理(找index_views视图)

    http://localhost:8000/news/xxx/xxx/xx
    http://localhost:8000/news/xx
    一律都交给 news 应用的 urls.py 去处理

    http://localhost:8000/music/xxx/xx/xx
    http://localhost:8000/music/xx
    一律都交给 music 应用的 urls.py 去处理

    http://localhost:8000/fun/1
    http://localhost:8000/fun/2

    http://www.baidu.com
    http://localhost:8000

    http://localhost:8000/sport/******
    http://localhost:8000/music/******
    http://localhost:8000/news/*******

    http://localhost:8000 : 转交给 index 应用处理
    交给 index 应用中的 index_views处理
    http://localhost:8000/login : 转交给 index 应用处理
    交给 index 应用中的 login_views处理
    http://localhost:8000/register : 转交给index应用处理
    交给 index 应用中的 register_views处理

    http://localhost:8000/login
    http://localhost:8000/news
    urlpatterns = [
    url(r'^news/',include('news.urls'),
    url(r'^music/',include('music.urls')),
    url(r'^sport/',include('sport.urls')),

    # 访问路径如果不满足以上三者的话,则交给下面的url处理
    url(r'^',include('index.urls')),
    ]

    在 index.urls 中:
    urlpatterns = [
    #http://localhost:8000/
    url(r'^$',index_views),
    url(r'^login/$',login_views),
    url(r'^register/$',register_views),
    ]

    http://localhost:8000/news/
    交给 news 应用中的 index_views 处理
    http://localhost:8000/sport/
    交给 sport 应用中的 index_views 处理
    http://localhost:8000/music/
    交给 music 应用中的 index_views 处理

    6. Django 模板(Template)
    1、什么是模板
    模板是要动态给用户呈现的网页内容
    可以由Views(视图)呈现给用户
    其实就是网页 --->> 前后端结合的一个网页
    2、模板的设置
    在 settings.py 中 TEMPLATES 变量
    TEMPLATES = [
    {
    'BACKEND':'... ...',
    'DIRS':[... ..],
    ... ..
    },
    ]

    1、BACKEND :指定模板的搜索引擎,不用动
    2、DIRS :指定模板所存放的目录们
    DIRS = ['index.temp','music.temp']
    但是,如果DIRS中为空的话,那么Django会自动到每个应用中去搜索一个叫 templates 的文件夹作为模板管理目录
    推荐:
    1、DIRS 内容保持为空
    2、在每个应用中,创建一个templates的文件夹
    3、APP_DIRS
    True :首先从DIRS中指定的文件夹中查找模板,如果没找到的话,再搜索templates文件夹

    3、模板的加载方式
    1、使用 loader 获取模板,通过 HttpResponse 进行响应
    from django.template import loader

    def index_views(request):
    #1. 通过loader加载模板
    t=loader.get_template("01_index.html")
    #2. 通过t对象,将模板渲染成字符串(允许传递变量到模板中)
    html = t.render({})
    {} : 表示要传递给模板的变量们
    键:变量名
    值:变量的值
    如果没有变量传递的话, 允许省略{}
    #3. 通过HttpResponse将html响应给客户端
    return HttpResponse(html)

    2、使用 render 直接加载并返回模板
    from django.shortcuts import render

    def xxx_views(request):
    return render(request,'模板名称',{})



    4、模板的语法
    1、变量
    1、作用:允许将后端的数据传递给模板,在模板中,会根据变量的值进行显示

    2、Django中允许传递给模板做变量的数据类型
    数字,字符串,列表,元组,字典,函数,对象 不能传集合

    3、变量的语法
    1、loader
    dic= {
    '变量1':'值1',
    '变量2':'值2',
    }
    t = loader.get_template('xxx.html')
    html = t.render(dic)

    2、render
    dic= {
    '变量1':'值1',
    '变量2':'值2',
    }
    return render(request,'xx.html',dic)
    4、在模板中使用变量
    {{变量名}} 在浏览器解析这个变量

    2、标签
    1、什么是标签
    允许将服务器端的一些功能嵌入到模板中
    2、语法
    {% 标签内容 %}

    3、常用标签
    1、for
    {% for 变量 in 列表|元组|字典 %}
    <h2>{{forloop.parentloop}}:{{变量}}</h2>
    {% endfor %}
    在标签内部,允许使用 for 提供的内置变量 - forloop
    1、forloop.counter : 记录当前循环的次数(从1开始计数)
    2. forloop.first : 是否是第一个循环(第一项)
    3. forloop.last : 是否是最后一项 (返回的是true 或者false)
    4. forloop.parentloop 是一个指向当前循环的上一级循环的 forloop
    对象的引用(在嵌套循环的情况下)

    2、if 标签在 html 中可以放在任何位置
    {% if 条件 %}
    满足条件运行的内容
    {% endif %}

    条件中允许使用 比较运算符
    (> < >= <= == !=),逻辑运算符(not and or)
    注意: and 和 or 不能同时出现

    3、if ... else...
    {% if 条件 %}
    满足条件执行的内容
    {% else %}
    不满足条件执行的内容
    {% endif %}

    4、if ...elif ... elif ...else
    {% if 条件1 %}
    满足条件1运行的内容
    {% elif 条件2 %}
    满足条件2运行的内容
    {% else %}
    以上条件都不满足时运行的内容
    {% endif %}
    3、过滤器
    1、作用
    在显示变量的数据之前,允许对数据进行筛选或改变
    2、过滤器的语法
    {{变量|过滤器}}
    3、常用过滤器
    1、{{value|upper}}
    将value变为大写字符输出
    2、{{value|lower}}
    将value变为小写字符输出
    3、{{value|add:num}}
    累加num到value的后面
    4、{{value|floatformat:n}}
    将value四舍五入到 n 位小数
    5、{{value|truncatechars:n}}
    将字符串进行截取到n位字符(包含...)
    ... ...
    4、静态文件
    1、什么是静态文件
    不需要嵌入服务器端内容的文件,
    模板中所需要用到的 css,js,image,html等一些资源文件都是静态文件
    2、Django中静态文件的处理
    需要在 settings.py 中设置静态文件的访问路径 和 存储路径
    1、STATIC_URL
    指定静态文件的访问路径
    STATIC_URL='/static/'

    作用:
    当访问路径是 localhost:8000/static/***
    一律都去静态文件存储路径中搜索静态文件

    2、STATICFILES_DIRS
    指定静态文件存储路径
    STATICFILES_DIRS=(BASE_DIR,'static')
    'static':当前项目存放静态文件的目录名
    在项目的 static 目中 以及 所有应用的 static 目录中存放就是静态文件

    3、访问静态文件
    1、直接使用 localhost:8000/static/***
    <img src="/static/img/timg.jpeg">
    2、使用 {% static %}访问静态资源
    1、在模板的最顶层(在 <!DOCTYPE html> 之上)增加
    {% load static %}
    2、在使用静态资源时
    {% static %}表示的就是 静态资源访问路径
    <img src="{% static 'img/huiyuan.jpg'%}">

    作业:
    1、创建项目 fruitday (天天果园)
    2、创建应用 - index ,并注册
    3、配置 主路由文件
    localhost:8000/****
    交给 index 应用处理
    4、完善 fruitday 中的首页(模板) 和 登录页(模板)
    1、访问 localhost:8000/
    显示首页模板(html)
    2、访问 localhost:8000/login
    显示登录页模板(html)



    5、url() 的name参数
    url(regex,views,kwargs,name)
    name:允许为当前url设置别名,允许在Tempalte中使用别名找到对应的 url

    url(regex,views,name='别名')
    在Django模板中使用 name 实现url获取
    {% url '别名' %}

    1、通过 localhost:8000/news/09_child
    去往 news 应用下 01_params.html 模板
    一般网页跳转需要在链接中
    <a href='/news/09_child/'>点击转到另一个网页</a>
    的 href 写 端口号后面完整的路径, 没有 /news/ 会跳转错误

    如果跳转的页面 有别名 ,可以写成下面的情况
    <a href=" {% url 'child' %} ">点击转到另一个网页</a>

    2、在模板中增加一个超链接
    localhost:8000/news/02_cal/35/72
    链接中增加两个参数,分别都是1位以上的数字
    在链接对应的视图中,对两个数字进行相加并打印在网页中(使用name别名)


    6、模板的继承
    1、什么是模板的继承
    当多个模板(网页)具备大部分相同的内容时,就可以使用继承的方式,将相同的内容继承过来,
    再增加/修改属于自己的内容即可
    2、模板的继承语法
    1、在父模板中
    必须要标识出哪些内容是允许被修改的
    标签:
    {% block 名称 %}
    父模板中的内容
    {% endblock %}
    block 作用:
    定义在子模板中允许被修改的地方
    1、在父模板中,是正常显示的
    2、在子模板中,如果不修改block中的内容的话则按照父模板中的内容进行显示
    2、在子模板中
    1、在最顶层增加一句话
    {% extends '父模板的名称' %}
    2、增加 block 标签,编写/改写属于自己的内容
    {% block 名称 %}
    子模板中的内容
    {% endblock %}

    在子模板中的block会覆盖父模板中同名的block的内容


    在子模板中, 要继承的父模板 如果有参数, 需要子模板在视图函数中重新给父模板传 参数
    1. 继承的参数不能冲突
    2. 在参数存在判断, 要考虑参数的循环

    7、 模型 - Models day3 文件
    1、什么是模型
    模型,是根据数据库中数据表的结构来创建出来的class。
    每一张表到编程语言中就是一个class,表中的每一个列,
    到编程语言中就是class中的一个属性。在模型中还能完成对数据的CRUD操作。
    C:Create
    R:Retrieve
    U:Update
    D:Delete
    2、创建 和 使用模型 - ORM
    1、什么是ORM
    ORM:Object Relational Mapping
    简称:ORM , O/RM , O/R Mapping
    中文:对象关系映射
    三大特征:
    1、数据表 到 类(class)的映射
    将数据表 自动 生成一个class类
    将class类 自动 生成数据库中的一张表
    2、数据类型的映射
    允许将表中字段的数据类型 自动 映射成编程语言中对应的数据类型

    也允许将编程语言的数据类型 自动 映射成表中的字段的数据类型
    3、关系映射
    数据库中表的关联关系:
    一对一,一对多,多对多

    将表与表之间的关系也映射到编程语言的class中,通过创建 类与类(对象与对象)之间的关系来完成
    2、ORM的优点
    1、提高了开发效率,能够自动完成表到对象的映射,可以省略庞大的数据访问层
    2、不用SQL编码,也能够完成对数据的CRUD操作

    3、创建 和 配置数据库
    1、创建数据库(支持中文) 在mysql 中创建数据库
    create database 数据库名 default charset utf8 collate utf8_general_ci;

    创建数据库:webdb
    2、Django中数据库的配置
    在 settings.py 中配置数据库的信息
    DATABASES = {
    'default':{
    'ENGINE':'django.db.backends.mysql',
    'NAME':'...',
    }
    }

    连接MySQL的配置:
    1、ENGINE:引擎
    django.db.backends.mysql
    2、NAME:要连接到的数据库名称
    3、USER:用户名称,通常为 root
    4、PASSWORD:密码,123456
    5、HOST:要连接的主机,本机的话 localhost 或 127.0.0.1
    6、PORT:端口,MYSQL的是 3306
    注意:
    Django 中连接mysql的话依赖于 pymysql
    安装pymysql
    sudo pip3 install pymysql==0.7.11

    __init__.py 在主工程下的 init文件
    import pymysql
    pymysql.install_as_MySQLdb()

    4、数据库的同步操作 在models.py 中创建了class 再执行这两步骤
    1、./manage.py makemigrations
    作用:将每个应用下的 models.py 文件生成一个数据库中间文件,并保存在 migrations 文件夹中

    2、./manage.py migrate
    作用:将每个应用下的 migrations 文件夹中的中间文件同步到数据库中

    5、编写Models
    1、注意
    1、Models中的每个class都称为 模型类(Model类) 或 实体类(Entry)
    实体:表示的就是数据表中的一条记录
    实体完整性:约束表中的记录不完全重复
    2、Models中的每个类都必须继承自models.Model
    2、举个例子
    在 models.py 中
    from django.db import models

    # 创建 Publisher 模型类
    # 表示 出版社 的信息,并包含以下属性
    # 1. name :出版社名称
    # 2. address :出版社的地址
    # 3. city :出版社所在城市名称
    # 4. country :出版社所在国家名
    # 5. website :出版社的网址
    class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=20)
    country = models.CharField(max_length=20)
    website = models.URLField()
    3、Django中提供的数据字段 和 字段选项
    语法:
    属性 = models.数据字段(字段选项)

    数据字段(Field Type)
    1、BooleanField()
    2、CharField() varchar
    3、DateField()
    4、DateTimeField()
    5、DecimalField() float
    6、EmailField() # 存电子邮件 - varchar
    7、FloatField()
    8、ImageField() # 存图片路径 - varchar
    ImageField(upload_to = 'static/***/***')
    9、IntegerField() int
    10、URLField() # 存网站地址 - varchar
    11、TextField() # 存大量数据 - text
    字段选项(Field Options)
    1、max_length
    指定数据的最大长度
    2、default
    为当前属性(字段)指定默认值
    3、null
    指定当前属性(字段)是否允许为空,默认是false
    练习:
    1、在 models.py 中 追加2个class
    1、Author - 作者
    1、name - 姓名
    2、age - 年龄
    3、email - 邮箱(允许为空)
    2、Book - 图书
    1、title - 书名
    2、publicate_date - 出版时间

    ====================================================6.24

    8、Models - 模型 --2

    1、数据的版本切换
    1、./manage.py migrate
    执行所有应用中最新版本的 数据库中间文件
    2、./manage.py migrate 应用名称 版本号
    如: ./manage.py migrate index 0002
    执行 index 应用中 版本号为 0002的中间文件
    2、通过数据库自动导出Models
    ./manage.py inspectdb > 文件名.py

    2、模型中的 CRUD
    所有的操作均在 视图中(Views) 执行 实例中 entry 是类名

    要先 把models.py 导入 到 views.py 文件中
    1、通过ORM向DB中增加数据
    1、Entry.objects.create(属性=值,属性=值)
    Entry:具体要操作的Models类

    ex:
    Author.objects.create(name='sf.zhang',age=85)

    2、创建一个 Models 对象 Author,其中传入数据,并通过 save() 完成增加
    obj = Author(属性=值,属性=值)
    obj.save()
    3、使用字典构建对象Author,其中传入字典(字典传参),并调用其 save() 完成增加
    dic = {
    '属性1':'值1',
    '属性2':'值2',
    }

    obj = Author(**dic)
    obj.save()
    练习:
    使用三种方式 分别向 index_book,index_publisher 中各增加三条数据

    2、查询操作(重难点)
    通过 Entry.objects 调用查询接口
    1、基本查询操作
    语法:all()
    用法:类名.objects.all()
    返回: QuerySet (查询结果集,封装了若个字典的一个列表)
    ex:
    authors = Author.objects.all();
    等同于:select * from [index_author];
    authors 是结果集对象 ,通过 for循环 + 每个子对象.字段名 打印具体内容
    2、查询指定列操作
    语法:values('列1','列2',...)
    用法:Entry.objects.values('列1','列2')
    返回:QuerySet
    ex:
    Author.objects.values('name')
    等同于:select name,age from index_author
    注意:
    values() 可以用在所有的查询结果集的方法的后面

    Author.objects.all().values('列1','列2')

    2. 返回的数据是列表封装的元组
    Author.objects.values_list('name','age')

    如: <QuerySet [('老舍', '55'), ('sf.zhang', '85'),
    ('龙在天', '85'), ('啧啧啧', '551')]>


    3、order_by()
    作用:排序
    语法:order_by('-列1','列2',...)
    列前加 "-" 表示降序
    用法:
    Entry.objects.order_by('列')
    Entry.objects.all().order_by('列')
    ex:
    Author.objects.order_by('-age')

    4、对条件取反
    语法:exclude()
    用法:Entry.objects.exclude(条件)
    ex:
    1、Author.objects.exclude(id=3)
    select * from author where not (id=3)
    2、Author.objects.exclude(id=3,age=85)
    select * from author where not (id=3 and age = 85)

    5、根据条件查询部分行数据(重难点)
    语法:filter(参数)
    用法:Entry.objects.filter(参数)
    1、使用 Entry 中的属性作为查询参数
    多个参数的话,使用 , 隔开,映射到sql语句中使用 and 进行关联的
    ex:
    1、Author.objects.filter(id=1)
    select * from author where id=1
    2、Author.objects.filter(id=1,name='莫言')
    select * from author where id=1 and name='莫言'

    2、通过 Filed Lookups(查询谓词/查询表达式) 完成复杂条件
    查询表达式: 每个查询表达式都是一个独立的查询条件, 可以用在所有的有查询条件位置处
    查询谓词:每个查询谓词都是一个独立的查询条件,可以用在所有的 有查询条件的位置处
    1、__exact
    作用:等值判断
    用法:Entry.objects.filter(属性__exact=值)
    比如:
    Author.objects.filter(id__exact=1)
    select * from author where id=1
    2、__contains
    作用:判断属性中是否包含指定关键字(模糊查询)
    比如: Author.objects.filter(name__contains='ao')
    select * from author where name like '%ao%';
    3、__lt
    作用:判断属性值 小于 指定值的所有记录
    4、__lte:
    作用:判断属性值小于等于指定值的所有记录
    5、__gt:
    作用:判断属性值大于指定值的所有记录
    6、__gte:
    作用:判断属性值大于等于指定值的所有记录

    7、__startwith
    作用:判断属性值是以 ** 开头的
    用法:Entry.objects.filter(列__startwith='xx')
    sql:select * from author where 列 like 'xx%'

    6、查询只返回一条数据
    语法:get(条件)
    用法:Entry.objects.get(查询条件/谓词)
    注意:
    该函数只适用于 返回一条记录时使用

    3、修改数据
    1、修改单个数据
    1、通过 get() 得到要修改的实体对象
    2、通过实体对象的属性修改属性值
    3、再通过实体对象的save()保存回数据库

    au = Author.objects.get(id=1)
    au.name = '王宝强'
    au.age = 35
    au.save()
    2、批量修改数据 update 不能出现在get()后面 可以在filter() all() 后面
    调用查询结果集的update()即可
    Author.objects.all().update(属性=值,属性=值)

    Author.objects.all().update(age=75)

    4、删除数据
    调用实体对象/查询结果集 的 delete() 即可
    1、删除单个对象
    obj = Author.objects.get(id=1)
    obj.delete()
    2、删除多个对象(结果集)
    authors = Author.objects.all()
    authors.delete()

    练习:
    完成删除操作
    1、点击删除时,跳转到 delete_views 视图中
    http://localhost:8000/07_delete/ID
    2、在 delete_views中,接收一个参数,表示要删除的用户的ID
    3、在视图中,将该ID对应的用户删除出去

    作业1:
    在查询列表的基础上完成下列操作
    1、点击修改时,将该用户显示在 04_au.html 上
    2、每个数据都用文本框显示

    作业2:
    改版删除操作
    1、在 Author 实体中增加一个属性 isActive ,默认值为 True
    2、在查询列表页面中,点击删除时,将要删除的用户的 isActive 更改为 False
    3、查询所有数据时,查询 isActive 为 True的用户,并显示在查询列表页面上


    ======================================================6.25

    1 。转发 和 重定向
    1. 转发
    在视图函数中,进行该视图需求操作后,返回另外一个视图函数

    2 。重定向
    1、什么是重定向
    浏览器重新向新的访问地址发送请求(服务器端)
    2、语法
    return HttpResponseRedirect(地址)

    2. ORM操作
    更新Author 表中 所有人的年龄都加10
    update index_author set age=age+10
    下面这样写是错误的
    Author.objects.all().update(age=age+10) # 错误

    !!!!!!!!!!!! 先在views.py 文件导入 from django.db.models import F,Q

    1. F() 操作
    作用:用于在执行操作中,获取某列的值,

    语法:F('列名')

    from django.db.models import F
    Author.objects.all().update(age=F('age')+10)

    2、Q() 操作
    查询条件满足多个
    Author.objects.filter(id=1,age=35) //两个条件都满足
    select * from author where id=1 and age=35

    作用:在查询条件中,可以完成 或(or) 的操作
    语法:
    from django.db.models import Q
    Q(表达式)|Q(表达式)

    # 查询 id为1 或 年龄 大于等于 85 的人的信息
    Author.objects.filter(Q(id=1)|Q(age__gte=85))
    select * from author wehre id=1 or age >= 85

    3、原生的数据库操作方法
    1、查询
    函数:raw(sql语句)
    语法:aulist = Entry.objects.raw(sql)
    返回:QuerySet 用for 循环打印出来
    for au in sulist:
    print(au.name, au.age)

    2、增删改
    def doSQL(request):
    with connection.cursor() as cursor: # 游标
    sql = 'delete from author where ...'
    cursor.execute(sql)
    return HttpResponse('...')


    3、使用后台管理 Models 用管理员来操作数据库 帮助文档/The models layer/Meta options
    1、后台的配置
    登录地址:localhost:8000/admind

    创建后台管理员
    ./manage.py createsuperuser
    Username: 输入用户名,默认为 tarena
    Email Address: 电子邮件地址,
    Password:密码
    Password(again):重复密码

    2、基本管理
    1、在应用中的 admin.py 中注册要管理的数据
    1、admin.py
    作用:注册需要管理的Models,只有在此注册的Models才允许被管理
    2、注册Models
    from .models import *
    admin.site.register(Entry1)
    admin.site.register(Entry2)
    2、修改 models.py 处理显示内容
    1、在 models.py 中的各个 class 追加
    def __str__(self):
    return self.name
    在后台显示该数据表显示的每条记录开头内容
    列表页的开头内容

    2、通过 Models 类定义一个内部类 Meta,在这个内部类定义其展现形式
    class Author(models.Model):
    ... ... ...
    ... ... ...
    ... ... ...
    # 增加内部类 见 day3/idnex/models.py
    class Meta:
    1、db_table
    指定该实体类对应到表的名称(对应到数据库显示的名称) 默认的是应用名+类名
    2、verbose_name
    定义该实体类在 admin(后台管理的管理页) 中显示的名字(单数)
    管理页,显示所有的表,用户信息
    3、verbose_name_plural
    效果同上,是复数形式
    4、ordering
    指定显示的数据们的排序规则,取值是一个列表,默认是升序排序,降序的话则使用 "-"

    练习:
    1、修改 Publisher 的 Meta
    1、更改表名为 publisher
    2、修改展示名称 "出版社"
    2、修改 Book 的 Meta
    1、更改表名为 book
    2、修改展示名称 "书籍"
    3、指定排序 - 按照出版时间降序排序
    3、高级管理 admin.py
    1、在 admin.py 中创建高级管理类
    1、定义 EntryAdmin 类,继承自admin.ModelAdmin
    如: class AuthorAdmin(admin.ModelAdmin):
    pass
    2、注册 高级管理类
    admin.site.register(Entry,EntryAdmin)
    例:
    admin.site.register(Author,AuthorAdmin)
    2、定制信息 允许在 EntryAdmin 中增加的属性
    1、list_display
    作用:指定在 列表页 中能够显示的字段们有哪些
    取值:由属性名组成的元组或列表
    ex:
    list_display = ['name','age','email'] 在列表页显示3个字段(3个属性)

    2、list_display_links
    作用:定义在列表也中能够连接到详情页(单条表记录具体信息)的字段们
    点击定义了的属性,就能进入详情页
    取值:由属性名组成的元组或列表
    注意:取值必须出现在 list_display 中
    如: list_display_links = ['email']


    3、list_editable
    作用:指定在列表页中就允许修改的字段们 就不用在详情页修改了
    取值:由属性名组成的列表或元组
    注意:取值不能出现在list_display_links 中,但必须出现在list_display

    4、search_fields
    作用:添加允许被搜索的字段们
    取值:由属性名组成的元组或列表

    5、list_filter
    作用:在列表页的右侧增加过滤器,实现快速筛选
    取值:有属性名组成的元组或列表

    6、date_hierarchy 必须该表有时间的属性(字段)
    作用:在列表页顶部增加时间选择器,所以取值必须是DateField 或 DateTimeField 的列
    如:
    date_hierarchy = 'publicate_date'

    7、fields
    作用:在详情页面中,指定显示哪些字段们,并按照什么样的顺序显示
    取值:由属性名组成的元组或列表

    8、fieldsets
    作用:在详情页面中,对字段们进行分组显示 (分组便于对属性排列归纳显示或者隐藏)
    注意:fieldsets 不能与 fields 共存的
    语法:
    fieldsets = (
    (
    '分组名称',{
    'fields':('属性1','属性2'),
    'classes':('collapse'), # 让分组的栏目初始化是显示还是隐藏(此为隐藏)
    }
    ),
    )


    练习:
    为 Publisher增加高级管理功能
    1、在 列表页中显示 name,address,city 属性
    2、address 和 city 是可编辑的
    3、右侧曾加一个过滤器,允许按照 address 和 city 进行筛选
    4、分组显示
    name,address,city 为"基本选项"
    country,website 为"可选选项",并可以折叠


    4、关系映射 - Django中的连接查询
    1、一对一映射
    1、什么是一对一
    A表中的一条记录只能与B表中的一条记录相关联
    典型代表:一夫一妻制
    数据库中实现:
    A表:设置 主键
    B表:增加一列,并引用自A表的主键,还得增加一个唯一约束(唯一性)
    2、语法
    在关联的两个类中的任何一个类中: 在models.py 中加 新的属性
    属性 = models.OneToOneField(Entry)
    3、查询
    class Wife(models.Model):
    ... ...
    author = models.OneToOneField(Author,null=True) 默认值为null ,才能导入数据库

    正向查询:通过 wife 找 author
    # 获取 id为1 的 Wife的信息
    w = Wife.objects.get(id=1)
    # 再获取 w 的关联的 author
    a = w.author
    反向查询:通过 author 找 wife
    # 获取 id 为1 的 Author 的信息
    a = Author.objects.get(id=1)
    # 再获取 a 的关联的 wife
    w = a.wife

    wife = author.wife 这里author 这个表默认增加了一个隐式属性,所以可以直接用这个属性

    wife 是由Django通过OneToOneField在Author中默认增加的一个隐式属性


    ========================================================== 6.26


    2、一对多映射
    1 .什么是一对多
    A表中的一条数据可以与 B表中的多条数据关联
    但是 B表中的数据只能与 A表的一条数据关联

    2、在数据库中的体现
    通过 外键(Foreign Key) 来体现一对多
    在 "多" 表中增加外键(Foreign Key) 对 "一" 表的主键进行引用


    3、语法
    使用 外键(Foreign Key)
    在 "多" 的实体中,增加: 在models.py 中增加 新的属性
    属性 = models.ForeignKey(Entry)
    ex:
    Book(多) 和 Publisher(一)

    class Book(models.Model):
    .... ....
    .... ....
    publisher = models.ForeignKey(Publisher,verbose_name='出版社是',null=True)

    4、查询
    Book(多) 和 Publisher(1)

    在多的实体中增加对1的实体的引用

    class Book(models.Model):
    .... ....
    publisher = models.ForeignKey(Publisher,null=True)

    1、正向查询 - 通过 Book 查询 Publisher
    book = Book.objects.get(id=1)
    publisher = book.publisher

    2、反向查询 - 通过 Publisher(1) 查询 Book(多)
    Django 会在 1 的实体 中自动增加 关联对象_set 属性, 用于查询 "多" 的数据, 此为隐式属性

    如 Django默认会在Publisher中增加book_set属性

    pub = Publisher.objects.get(id=1)
    books = pub.book_set.all()


    3、多对多映射 //必须创建第三张关系表
    1、什么是多对多
    A表中的一条记录可以与B表中的任意多条记录匹配
    B表中的一条记录可以与A表中的任意多条记录匹配

    ex:
    作者 与 书籍 一个人除多本书 多个人合作出一本书
    2、在数据库中体现
    必须创建第三张表(自动创建的),关联 涉及到的两张数据表
    3、语法
    在任何一个实体类中,增加:(只是在一个表增加)
    entry = models.ManyToManyField(Entry)
    ex:
    class Author(models.Model):
    ... ...
    ... ...
    book = models.ManyToManyField(Book)


    1. 创建完成再重新 导入数据库
    2. 在该数据库webdb 查到第三张关系表 author_book
    3. 该表有 id author_id book_id 三个字段
    4. author_id book_id 是唯一索引

    4、查询
    class Author(models.Model):
    ... ...
    ... ...
    book = models.ManyToManyField(Book)

    1、正向查询 - 通过 Author 查询所有的 Book
    author = Author.objects.get(id=1)
    book_list = author.book.all()
    通过 关联属性.all() 查询所有的关联数据

    2、反向查询 - 通过 Book 查询所有的 Author
    book = Book.objects.get(id=1)

    #Django 会在 Book 表中增加一个隐式属性 author_set

    author_list = book.author_set.all()

    练习:
    创建 Author 与 Publisher 多对多的关系
    1、查询 贾乃亮 签约的所有 出版社
    2、查询 北京大学出版社下的所有 签约作者

    2、自定义查询对象 - objects 在models.py 声明
    在objects自身提供的查询API函数基础上,增加一部分自定义的执行函数
    1、声明类 EntryManager ,继承自models.Manager
    允许在 EntryManager 内部添加自定义函数

    class EntryManager(models.Manager):
    def 函数名(self,自定义参数列表):
    ... ...
    return ... ...
    2、使用 EntryManager 覆盖 Models中的objects
    class Entry(models.Model):
    objects = EntryManager()

    练习:
    1、为 Author 指定自定义 objects 对象
    添加自定义函数:
    1、查询年纪小于指定年纪的所有作者的信息
    2、为 Book 指定自定义 objects 对象
    添加自定义函数:
    1、查询书名中包含指定关键字的书籍的数量


    3、HttpRequest
    1、HTTP 协议
    1、请求(request)
    Request Headers (View Source):
    第一行:请求起始行
    第二行: 请求消息头
    第三行: 请求主体
    请求方法 请求路径 协议版本/版本号
    2、响应(response)
    Response Headers (View Source):
    第一行:响应起始行
    协议版本/版本号 响应状态码 原因短句
    第二行: 响应消息头
    第三行: 响应主体
    响应状态吗:
    1、200 :服务器正常接收请求以及给出响应
    原因短句:OK
    2、304 :从缓存中获取的数据
    原因短句:Not Modified
    3、403 :未获得权限
    原因短句:Forbbiden
    4、404 :请求资源未找到
    原因短句:Not Found
    5、500 :服务器端程序出错
    原因短句: ...
    2、HttpRequest介绍
    1、什么是HttpRequest
    HttpRequest,在Django中是请求对象的封装体现。封装了请求过程中的所有的信息。
    在Django中,HttpRequest 被化身成了 request 封装到了视图处理函数中作为参数,
    在调用视图的时候自动传入

    2、HttpRequest中的主要内容
    1、request.scheme : 请求协议
    2、request.body : 请求主体
    3、request.path : 请求路径
    4、request.get_host() : 请求的主机地址/域名
    5、request.method : 请求方法
    6、request.GET : get请求方法的提交数据
    7、request.POST : post 请求方法的提交数据
    8、reqeust.COOKIES : cookies中的数据
    3、获取请求提交的数据
    1、GET请求
    request.GET['名称']
    2、POST请求
    request.POST['名称'] 获取POST传过来的值 POST['值变量'] 值变量是在form表单提交过来的
    见 day3 index 应用

    4、CSRF 跨站点攻击
    目的:为了解决跨站点发送post请求

    解决方案:
    1、settings.py中
    删除 CsrfViewMiddleWare 中间件 不要暗号
    2、在视图中增加 @csrf_protect
    3、在模板中 <form>下的第一行增加:
    {% csrf_token %} 相当于服务器给浏览器发HTML之前,给HTML一个暗号,
    在HTML返回post请求, 服务器会根据暗号判断这个请求是不是合法的(是不是服务器发过去的HTML)

    ==========================================6.27


    1 .地址栏拼参数
    手动拼写参数到提交地址的后面
    http://地址/?名称1=值1&名称2=值2

    uname = request.GET.get('uname','')
    upwd = request.GET.get('upwd','')

    1、使用 forms 模块处理表单
    1、forms 模块的作用
    通过 forms 模块,允许将表单控件 与 py 文件相结合,可以自动生成表单控件

    2、在forms.py 文件 -->使用 forms 模块--> 创建表单控件的类
    1、创建 forms.py 文件 在APP文件夹下创建
    2、导入 forms
    from django import forms
    3、创建 class,一个class对应一个表单
    该class必须继承自forms.Form
    4、在 class 中创建属性
    一个属性对应着一个表单控件
    (参考文档)

    3、在模板中,解析 form 对象 day6 index form.py 04_form.html 05_form/
    1、注意
    1、需要自定义 <form>
    2、需要自定义 提交按钮
    2、处理方法 在HTML解析
    1、手动解析
    在视图中创建 forms.Form 的对象,并发送到模板中

    ex:
    form = RemarkForm()
    return render(request,'xx.html',locals())

    手动解析:
    模板中:
    {% for field in form %}
    {{field.label}} : 表示控件前的文本
    {{field}} : 表示控件
    {% endfor %}
    <p> //加提交按钮
    <input type="submit" value="提交">
    </p>
    如:
    <!-- 手动解析 加提交按钮-->
    <form action="">
    {% for field in form %}
    <p>
    {{field.label}}:{{field}}
    </p>
    {% endfor %}
    <p>
    <input type="submit" value="提交">
    </p>
    </form>


    2、自动解析
    1、{{form.as_p}}
    将表单中的每个属性都解析成一个 p 标记,里面再包含这个属性 对应的控件以及标签
    v 如:
    <form action="">
    {{form.as_p}}
    <p>
    <input type="submit" value="提交">
    </p>
    </form>

    解析成

    <form action="">

    <p>
    <label for ="id_subject">标题:</label> <input type="text" name="subject">
    </p>
    <p>
    <label for ="id_email">邮箱:</label> <input type="email" name="email">
    </p>
    ......
    ....
    .
    .
    ....
    <p>
    <input type="submit" value="提交">
    </p>
    </form>

    2、{{form.as_ul}}
    将表单中的每个属性都解析成一个 li 标记,再显示表单的控件以及标签
    注意:需要自定义 <ul></ul> 或 <ol></ol>
    <ol>
    {{form.as_ul}}
    </ol>

    3、{{form.as_table}}
    将表单中的每一个属性都解析 成一个tr标记, 再显示标签以及控件


    4、在视图中,通过 forms.Form 快速获取表单数据 POST请求时 获取数据
    1、通过 forms.Form 的构造函数,接收 post 数据
    意思是,还是找创建form表单的类的对象来接收数据

    form = XXXForm(request.POST) 表单对象--》带有所有从前端表单控件提交的所有数据

    2、需要让form通过验证后,再取值
    form.is_valid()
    返回 true : 提交的数据已经通过所有验证,允许接收表单提交的数据
    返回 false: 提交的数据中有暂未通过验证的
    3、获取表单提交的数据
    通过 form.cleaned_data (字典) 接收提交的数据
    cd = form.cleaned_data
    print(cd['subject']) # 获取 subject 表单控件的值
    4. 当验证失败, 即 is_valid() 为flase
    会有错误信息 form.errors

    练习:
    1、在 forms.py 中追加一个 RegisterForm 类
    2、增加以下属性,并生成到regsiter.html 显示成表单控件
    1、uname :文本框
    2、upwd :密码框
    3、uemail :邮件框
    4、uage : 文本框
    3、在 register.html中增加 form 和 submit
    4、点击提交按钮时,将数据插入到数据库中
    创建数据库 day7 , 创建 Models-Users

    5、forms 的高级处理 -----> 根据数据库现有的表创建表单
    将 Models 和 Forms 结合到一起使用
    1、在 forms.py 中,创建class,继承自 forms.ModelForm
    2、创建内部类 :Meta,关联 Form 和 Models
    属性
    1、model : 指定要关联的Model类
    2、fields :从models中取哪些字段生成控件
    1、取值 "__all__",全部的属性都要生成表单控件
    2、指定一个列表,声明允许生成表单控件的属性名
    3、labels :每个属性关联的label,取值为 字典
    labels = {
    '属性名':'label文本',
    '属性名':'label文本',
    }

    ===================================================================6.28
    1、使用forms模块处理表单
    1、内置小部件
    1、什么是小部件
    小部件(Widget),表示的是生成到页面中的控件的类型以及其他属性
    2、常用小部件
    1、TextInput : type="text"
    2、NumberInput : type="number"
    3、EmailInput : type="email"
    4、URLInput: type="url"
    5、PasswordInput : type="password"
    6、HiddenInput : type="hidden"
    7、CheckboxInput : type="checkbox"
    8、Textarea : <textarea></textarea>
    9、Select : <select></select>
    3、小部件的使用
    1、继承自 forms.Form
    1、语法:
    1、基本版
    属性 = forms.CharField(
    label = "标签",
    widget = forms.小部件类型
    )

    ex:
    upwd = forms.CharField(
    label='密码',
    widget=forms.PasswordInput
    )
    2、高级版
    属性 = forms.CharField(
    label="标签",
    widget=forms.小部件类型(
    attrs={
    '属性名1':'属性值',
    '属性名2':'属性值',
    ... ...
    }
    )
    )
    uname =forms.CharField(label='用户',widget = forms.TextInput(
    attrs={
    'placeholder':'输入用户名',
    'class':'form-control',
    }
    ))


    2、继承自 forms.ModelForm
    class WidgetForm(forms.ModelForm):
    class Meta:
    model=Users
    fields = '__all__' #['属性1','属性2']
    labels = {
    '属性1':'标签1',
    '属性2':'标签2',
    }
    widgets = {
    '属性1':forms.小部件类型(attrs={ ... }),
    '属性2':forms.小部件类型(attrs={ ... }),
    }
    2、cookies
    1、什么是cookies
    cookies 是一种数据存储技术
    将一段文本保存在客户端(浏览器)的一种技术,并可以长时间保存
    2、cookies的使用场合
    1、保存登录信息
    2、保存搜索关键词
    3、django 中使用 cookies
    1、设置cookies(将数据保存到客户端)
    语法:
    响应对象.set_cookie(key,value,expires)
    key:cookie的名字
    value:cookie的值
    expires:保存时间,以s为单位
    1、不使用模板
    resp=HttpResponse('给客户端的一句话')
    resp.set_cookie('key','value',expires)
    return resp

    ex:
    resp = HttpResonse('添加Cookie成功')
    resp.set_cookie('uname','zsf',60*60*24*366)
    return resp
    2、使用模板
    resp = render(request,'xxx.html',locals())
    resp.set_cookie(key,value,expires)
    return resp
    3、使用重定向
    resp = HttpResponseRedirect('/地址/')
    resp.set_cookie(key,value,expires)
    return resp

    练习:
    1、完成 fruitday 登录操作
    2、判断手机号 和 密码是否正确
    3、如果正确的话,并且勾选了 记住密码的话,则将登录信息保存进 cookie ,存期为 1 年
    2、获取cookies(将数据从客户端中获取出来)
    request.COOKIES
    封装了当前访问站点下的所有的cookie信息
    练习:
    1、完成fruitday的登录
    2、当用户访问登录路径时
    先判断cookie中是否有登录信息(id,uphone)
    如果包含登录信息的话,则可以直接跳往至首页
    否则 :显示登录页
    3、session - 会话
    1、什么是session
    session(会话),实际上就是在服务器上为每个浏览器开辟一段空间,用于保存相关的请求信息
    2、session的使用场合
    session也是为了存放数据而存在的。
    通常会把服务器端要经常用到的客户端的数据保存进去
    3、Django中使用session
    1、设置 session 的值
    request.session['key'] = 值
    request.session.set_expiry(time):设置session的过期时间,如果设置为0的话,则表示关闭浏览器session就失效
    2、获取session的值
    request.session.get('key')

    3、删除 session的值
    del request.session['key']
    4、在 settings.py 中,有关 session 的设置
    1、SESSION_COOKIE_AGE
    作用:设置 sessionID 在 cookies 中的存活时间
    ex :
    SESSION_COOKIE_AGE = 60*30
    2、SESSION_EXPIRE_AT_BROWSER_CLOSE
    作用:设置浏览器关闭则清除服务器上对应的session空间
    ex:
    SESSION_EXPIRE_AT_BROWSER_CLOSE = True


    {
    'uid': '1',
    'csrftoken': 'NXJMZ8QvNVvWn1grj2f1IAJDp7S5aU5aGCO9tmrkz2GCkAulRaxqyGe63mwUHk9V',
    'uphone': '13912345678',
    'uname1': 'zsf'
    }

    name = forms.CharField() -->
    <input type="text" name="name" placeholder="">

    upwd = forms.CharField(label="",widget=forms.PasswordInput)

    Pycharm设置Django模板的HTML文件自动补全代码或标签

    https://blog.csdn.net/cf313995/article/details/83117421

  • 相关阅读:
    「2017 Multi-University Training Contest 7」2017多校训练7
    「2017 Multi-University Training Contest 2」2017多校训练2
    「CF838B」 Diverging Directions
    对拍程序
    ACM中的fread读入
    「UVA10766」Organising the Organisation(生成树计数)
    荣耻
    CCF 201812-3 CIDR合并
    CCF 201909-3 字符画
    CTSC 2017 游戏[概率dp 线段树]
  • 原文地址:https://www.cnblogs.com/chenpython123/p/11375021.html
Copyright © 2020-2023  润新知