• PYTHON3.Django_day03(见pdf)


    day02 回顾
       请求 HttpRequest 和响应 HttpResponse
         def xxx_view(request):
             if request.method == "GET":
                return HttpResponse("GET")
             elif request.method == 'POST':
                 return HttpResponse("POST")

      get请求:
         request.GET (QueryDict类型的字典)
         request.GET['key']
         request.GET.get('key', 默认值)
         request.GET.getlist('key')
       post 请求
         request.POST (QueryDict类型的字典)
         request.POST['key']
         request.POST.get('key', 默认值)
         request.POST.getlist('key')
         post请求要提交成功需要注释掉 CsrfViewMiddleware

    Django遵循的设计模式
        MTV
          M-model
          T-template
          V-view

    模板:
       动态的html
       配置模板
         settings.py
         TEMPLATES = [
           {
             DIRS = [os.path.join(BASE_DIR, 'templates')]
           }
         ]
         模板的加载
         def xxx_view(request):
             return render(request, 'xxx.html', locals())

        def xxx_view(request):
             t = loader.get_template('xxx.html')
             html = t.render(locals())
             return HttpResponse(html)

    模板的变量:
        {{ 变量名 }}
        {{ 变量名.列表的索引 }}
        {{ 变量名.字典的键 }}
        {{ 函数名 }}
        {{ 对象.方法名 }}
    模板的if 标签
         {% if xxxx %}
           ...
         {% elif yyyy %}
           ...
         {% else %}
            ...
         {% endif %}

    模板的 for 标签
         {% for 变量 in 可迭代对象 %}
            ...
         {% empty %}
            ...
         {% endfor %}
       内置变量forloop
            forloop.counter0
            forloop.counter
            forloop.revcounter
            forloop.revcounter0
            forloop.first
            ...
    模板的注释
       {#    #}
       {% comment %}
         ...
       {% endcomment %}
    过滤器
       {{ mystr | upper }}

    模板的继承
       myfile.html
       <html>
       ....
          {% block name1 %}
             <h1>父模板的内容 </h1>
          {% endblock name1 %}
          {% block name2 %}
             <h1> 标题1 </h1>
          {% endblock name2 %}
       </html>

      # myfile2.html
       {% extends 'myfile.html' %}
          {% block name2 %}
             <h1> 标题2 </h1>
          {% endblock name2 %}

    url 反向解板
        url(r'^xxx', xxx_view, name='xxx')
        url(r'^yyy(d+)(w+)', yyy_view, name='yyy')
       模板中
         {% url 'xxx' %}
         {% url 'yyy' '123' 'tedu'}
         /yyy123tedu


    day3笔记
    静态文件
        https://www.baidu.com/img/bd_logo1.png
    路由地址(url地址):
         /img/bd_logo1.png

    存储位置
         /home/tarena/django/day3/code/bd_logo1.png

    示例:
       路由:
         /static/images/meinv.png
       存储位置
         /home/tar.../mysite3/static/images/meinv.png

    路由
    127.0.0.1:8000/show_image


    mysql 数据
       mysql -u root -p123456

      用户名: root
       密码: 123456
       IP地址: 127.0.0.1
       端口号: 3306
       数据库名: 'mysite3_db'

      sql> create database mysite3_db default charset utf8 collate utf8_general_ci;

            create database mysite3_db default charset utf8 collate utf8_general_ci;


    练习:
        在bookstore/models.py 中再加入下个模型类
        class Author(....):
               # 姓名
               name = ...
               # 年龄
               age = .....
               # 其它自己尝试
         运行迁移,查看数据库的变量
         ----------------------------------------------------------------------------------------------------------------------------


    # 《Django 教程》
      - 讲师: 魏明择
      - 时间: 2019

    ## 目录
    <!-- TOC depthFrom:3 depthTo:5 -->

    - [静态文件](#静态文件)
    - [Django中的应用 - app](#django中的应用---app)
         - [创建应用app](#创建应用app)
         - [应用的分布式路由](#应用的分布式路由)
             - [django.conf.urls 里的include 函数](#djangoconfurls-里的include-函数)
    - [数据库 和 模型](#数据库-和-模型)
         - [Django下使用mysql数据库](#django下使用mysql数据库)
    - [模型(Models)](#模型models)
    - [Python 数据库模型 - Models](#python-数据库模型---models)
         - [字段选项](#字段选项)
         - [数据库迁移的错误处理方法](#数据库迁移的错误处理方法)
    - [数据库的操作(CRUD操作)](#数据库的操作crud操作)
         - [管理器对象](#管理器对象)
         - [创建数据对象](#创建数据对象)
         - [Django shell 的使用](#django-shell-的使用)
             - [查询数据](#查询数据)

    <!-- /TOC -->

    ### 静态文件
    <!-- 改进版需要添加静态文件的配置步骤... -->
    1. 什么是静态文件
         - 不能与服务器端做动态交互的文件都是静态文件
         - 如:图片,css,js,音频,视频,html文件(部分)
    2. 静态文件配置
         - 在 settings.py 中配置一下两项内容:
         1. 配置静态文件的访问路径
             - 通过哪个url地址找静态文件
             - STATIC_URL = '/static/'

             - 说明:
                 - 指定访问静态文件时是需要通过 /static/xxx或 127.0.0.1:8000/static/xxx
                 - xxx 表示具体的静态资源位置
         2. 配置静态文件的存储路径
             - 静态文件在服务器端的保存位置
             - STATICFILES_DIRS=(os.path.join(BASE_DIR,'static'),)

         3. 示例:
             ```py
             # file: setting.py
             STATICFILES_DIRS = [
                 os.path.join(BASE_DIR, "static")
             ]
             ```
    3. 访问静态文件
         1. 使用静态文件的访问路径进行访问
             - 访问路径: STATIC_URL=/static/

             -  示例:
                 ```py
                 <img src="/static/images/lena.jpg">
                 <img src="http://127.0.0.1:8000/static/images/lena.jpg">
                 ```
         2. 通过 {% static %}标签访问静态文件
                   {% static %}表示的就是静态文件访问路径

            1. 加载 static
                {% load static %}
             2. 使用静态资源时
                语法:{% static '静态资源路径' %}
                        <img src="{% static 'images/lena.jpg' %}">
         - 示例:
             - 路由配置文件
             ```py
             # file: url.py
             from . import views

            urlpatterns = [
                 url(r'^admin/', admin.site.urls),
                 url(r'^show_image', views.show_image)
             ]
             - 视图函数文件
             # file: views.py
             from django.shortcuts import render

            def show_image(request):
                 return render(request, "show_image.html")
             ```
             - 模板文件
             ```html
             <html>
             <head></head>
             <body>
             <h1>this is lena!</h1>
             <img src="/static/images/lena.jpg">
             <h1>this is templates lena!</h1>
             {% load static %}
             <img src="{% static 'images/lena.jpg' %}">
             </body>
             </html>
             ```
         - 练习:
             ```
             1. 127.0.0.1:8000 : 显示首页效果
             2. 127.0.0.1:8000/login : 显示登录页
             处理好所有的静态文件
             ```
         <!--
         - 练习:
             ```
             石头剪刀布游戏?
             ```
          -->

    ### Django中的应用 - app
    - 应用在Django项目中是一个独立的业务模块,可以包含自己的路由,视图,模板,模型

    ####  创建应用app
    - 创建步骤
         1. 用manage.py 中的子命令 startapp 创建应用文件夹
         2. 在settings.py 的 INSTALLED_APPS 列表中配置安装此应用

    - 创建应用的子命令
         - python3 manage.py startapp 应用名称(必须是标识符命令规则)
         - 如:
             - python3 manage.py startapp music

    - Django应用的结构组成
         1. `migrations` 文件夹
             - 保存数据迁移的中间文件
         2. `__init__.py`
             - 应用子包的初始化文件
         3. `admin.py`
             - 应用的后台管理配置文件
         4. `apps.py`
             - 应用的属性配置文件
         5. `models.py`
             - 与数据库相关的模型映射类文件
         6. `tests.py`
             - 应用的单元测试文件
         7. `views.py`
             - 定义视图处理函数的文件

    - 配置安装应用
         - 在 settings.py 中配置应用, 让此应用能和整个项目融为一体
             ```py
             # file : settings.py
            INSTALLED_APPS = [
                 ... ...,
                 '自定义应用名称'
             ]

            ```
         - 如:
             ```py
             INSTALLED_APPS = [
                 # ....
                 'user',  # 用户信息模块
                 'music',  # 收藏模块
             ]
             ```

    #### 应用的分布式路由
    - Django中,主文件夹可以不处理用户具体请求的,主文件夹的作用是做项目的初始化以及请求的分发(分布式请求处理)。具体的请求可以由应用来进行处理的
    - 如图:
         - ![](images/urls.png)
    ##### django.conf.urls 里的include 函数
    - 作用:
         - 用于分发将当前路由转到模个模块的 urlpatterns 进行分布式处理
    - 函数格式
         - include('App命字.url模块名')
    - 参数说明:
         - 模块`App命字/url模块名.py` 文件件里必须有urlpatterns 列表

    - 使用 include 函数让某个正则匹配后关联分支到某个app示例如下:
    ```py
    # file : <项目名>/urls.py
    from django.conf.urls import include

    urlpatterns = [
         url(r'^admin/', admin.site.urls),
         url(r'^music/', include('music.urls')),
    ]
    ```
    ```py
    # file : music/urls.py
    from django.conf.urls import url
    from . import views

    urlpatterns = [
         url(r'^page1', views.page1),
         url(r'^page2', views.page2),
         url(r'^page3', views.page3),
         # ...
    ]
    ```
    - 练习:
         ```
         1.创建四个应用
             1.创建 index 应用,并注册
             2.创建 sport 应用,并注册
             3.创建 news  应用,并注册
             4.创建 music 应用,并注册
         2.创建分布式路由系统
             主路由配置只做分发
             每个应用中处理具体访问路径和视图
             1. 127.0.0.1:8000/music/index
                 交给 music 应用中的 index_view() 函数处理
             2. 127.0.0.1:8000/sport/index
                 交给 sport 应用中的 index_view() 函数处理
             3. 127.0.0.1:8000/news/index
                 交给 news  应用中的 index_view() 处理处理
         ```

    ### 数据库 和 模型
    #### Django下使用mysql数据库
    1. 安装 pymysql包
         - 用作 python 和 mysql 的接口
             - `$ sudo pip3 install pymysql`
         - 安装 mysql 客户端(非必须)
             `$ sudo pip3 install mysqlclient`

    2. 创建 和 配置数据库
         1. 创建数据库
             - 创建 `create database 数据库名 default charset utf8 collate utf8_general_ci;`
             ```sql
             create database mywebdb default charset utf8 collate utf8_general_ci;
             ```
         2. 数据库的配置
             - sqlite 数据库配置
             ```
             # file: settings.py
             DATABASES = {
                 'default': {
                         'ENGINE': 'django.db.backends.sqlite3',
                         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
                 }
             }
             ```
             - mysql 数据库配置
             ```py
             DATABASES = {
                 'default' : {
                     'ENGINE': 'django.db.backends.mysql',
                     'NAME': 'mywebdb',  # 数据库名称,需要自己定义
                     'USER': 'root',
                     'PASSWORD': '123456',  # 管理员密码
                     'HOST': '127.0.0.1',
                     'PORT': 3306,
                 }
             }

             ```
         3. 关于数据为的SETTING设置
             1. ENGINE
                 - 指定数据库的后端引擎

                 ```
                 'django.db.backends.mysql'
                 'django.db.backends.sqlite3'
                 'django.db.backends.oracle'
                 'django.db.backends.postgresql'
                 ```
                 - mysql引擎如下:
                     - 'django.db.backends.mysql'

            2. NAME
                 - 指定要连接的数据库的名称

                 - `'NAME': 'mywebdb'`
             3. USER
                 - 指定登录到数据库的用户名

                 - `'USER':'root'`
             4. PASSWORD
                 - 接数据库时使用的密码。
                 - `'PASSWORD':'123456'`
             5. HOST
                 - 连接数据库时使用哪个主机。
                 - `'HOST':'127.0.0.1'`
             6. PORT
                 - 连接数据库时使用的端口。
                 - `'PORT':'3306'`
         3. 添加 mysql 支持
             - 安装pymysql 模块
                 - `$ sudo pip install pymysql`
             - 修改项目中__init__.py 加入如下内容来提供pymysql引擎的支持
                 ```py
                 import pymysql
                 pymysql.install_as_MySQLdb()
                 ```

    3. 数据库的迁移
         - 迁移是Django同步您对模型所做更改(添加字段,删除模型等) 到您的数据库模式的方式
         1. 生成或更新迁移文件
             - 将每个应用下的models.py文件生成一个中间文件,并保存在migrations文件夹中
             - `python3 manage.py makemigrations`
         2. 执行迁移脚本程序
             - 执行迁移程序实现迁移。将每个应用下的migrations目录中的中间文件同步回数据库
             - `python3 manage.py migrate`


    ### 模型(Models)
    - 模型是提供数据信息的数据库接口。
    - 模型是数据的唯一的、确定的信息源。 它包含你所储存数据的必要字段和行为。
    - 通常,每个模型对应数据库中唯一的一张表。每个模型的实例对应数据表中的一条记录

    - 模型说明:
         - 每个模型都是一个Python类,每个模型都是django.db.models.Model的子类。
         - 每一个模型属性都代表数据库中的一个表。
         - 通过所有这一切,Django为你提供一个自动生成的数据库访问API;

    ### Python 数据库模型 - Models
    1. ORM框架
         - ORM(Object Relationship Mapping)即对象关系映射,它允许你使用类和对象对数据库进行交互(使用类和对象和使用 SQL一样且更方便各种操作)。
         - ORM
             ```
             Object Relationship Mapping
               对象    关系         映射
             ```
         - 三大特征:
             1. 表 到 类的映射
             2. 数据类型的映射
             3. 关系映射
    2. 模型示例:
         - 此示例为添加一个 bookstore_book 数据表来存放图书馆中书目信息
         - 添加一个 bookstore 的 app
             ```shell
             $ python3 manage.py startapp bookstore
             ```
         - 添加模型类并注册app
             ```py
             # file : bookstore/models.py
             from django.db import models

            class Book(models.Model):
                 title = models.CharField("书名", max_length=50, default='')
                 price = models.DecimalField('定价', max_digits=7, decimal_places=2, default=0.0)
             # file : setting.py
             INSTALLED_APPS = [
                 ...
                 'bookstore',
             ]
             ```
         - 生成迁移脚本文件`bookstore/migrations/0001_initial.py`并进行迁移
             ```shell
             $ python3 manage.py makemigrations
             Migrations for 'bookstore':
             bookstore/migrations/0001_initial.py
                 - Create model Book
             $ python3 manage.py migrate
             Operations to perform:
             Apply all migrations: admin, auth, bookstore, contenttypes, sessions
             Running migrations:
             Applying bookstore.0001_initial... OK
             ```
         - 查看数据表
             ```
             $ mysql -u root -p
             mysql> show databases;
             +--------------------+
             | Database           |
             +--------------------+
             | information_schema |
             | mygoods            |
             | mysql              |
             | mywebdb            |
             | onlybuyp           |
             | performance_schema |
             | sys                |
             | test_db            |
             +--------------------+
             8 rows in set (0.00 sec)

            mysql> use mywebdb
             Reading table information for completion of table and column names
             You can turn off this feature to get a quicker startup with -A

            Database changed
             mysql> show tables;
             +----------------------------+
             | Tables_in_mywebdb          |
             +----------------------------+
             | auth_group                 |
             | auth_group_permissions     |
             | auth_permission            |
             | auth_user                  |
             | auth_user_groups           |
             | auth_user_user_permissions |
             | bookstore_book             |  <<== 新加表
             | django_admin_log           |
             | django_content_type        |
             | django_migrations          |
             | django_session             |
             +----------------------------+
             11 rows in set (0.00 sec)

            mysql> desc bookstore_book;
             +-------+--------------+------+-----+---------+----------------+
             | Field | Type         | Null | Key | Default | Extra          |
             +-------+--------------+------+-----+---------+----------------+
             | id    | int(11)      | NO   | PRI | NULL    | auto_increment |
             | title | varchar(50)  | NO   |     | NULL    |                |
             | price | decimal(7,2) | NO   |     | NULL    |                |
             +-------+--------------+------+-----+---------+----------------+
             3 rows in set (0.00 sec)
             ```
         - 表bookstore_book 即为模型 Book 类对应的数据表
             - id 为主键,当设定主键时会自动添加id字段为主键
             - 如果更新模型类 models.py 中的内容时需要运行 makemigrations 和 migrate 子命名来更新和同步数据库
             - 在开发阶段如果同步数据库出错。用 `sql> drop database 数据库名` 删除数据库后重新迁移数据库
             - 在 xxx_app/migrations/*.py 下的文件是自动生成的迁移脚本文件,可以手动删除且在下一次迁移时自动生成

    <!--
         - 使用Django 的 sqlmirate子命令 查看迁移脚本的 执行的SQL语句
         ```shell
         # 命令格式: python3 manage.py sqlmigrate app名称 迁移脚本编号0001
         $ python3 manage.py sqlmigrate bookstore 0001
         BEGIN;
         --
         -- Create model Book
         --
         CREATE TABLE `bookstore_book` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(50) NOT NULL, `price` double precision NOT NULL);
         COMMIT;
         $
         ```
      -->

    2. 编写模型类Models
         - 模型类需继承`自django.db.models.Model`
             1. Models的语法规范
                 ```
                 from django.db import models
                 class CLASSNAME(models.Model):
                     NAME = models.FIELD_TYPE(FIELD_OPTIONS)
                 ```
             1. CLASSNAME
                 - 实体类名,表名组成一部分,建议类名首字母大写
                 - 默认表名组成规范:
                     - 应用名称_classname
             1. NAME
                 - 类属性名,映射回数据库就是字段名
             1. FIELD_TYPE
                 - 字段类型:映射到表中的字段的类型

    3. FIELD_TYPE 类型及含义
         1. BooleanField()
             - 数据库类型:tinyint(1)
             - 编程语言中:使用True或False来表示值
             - 在数据库中:使用1或0来表示具体的值
         2. CharField()
             - 数据库类型:varchar
             - 注意:
                 - 必须要指定max_length参数值
         3. DateField()
             - 数据库类型:date
             - 作用:表示日期
             - 编程语言中:使用字符串来表示具体值
             - 参数:
                 - DateField.auto_now: 每次保存对象时,自动设置该字段为当前时间(取值:True/False)。
                 - DateField.auto_now_add: 当对象第一次被创建时自动设置当前时间(取值:True/False)。
                 - DateField.default: 设置当前时间(取值:字符串格式时间如: '2019-6-1')。
                 - 以上三个参数只能多选一
         4. DateTimeField()
             - 数据库类型:datetime(6)
             - 作用:表示日期和时间
             - auto_now_add=True

        5. DecimalField()
             - 数据库类型:decimal(x,y)
             - 编程语言中:使用小数表示该列的值
             - 在数据库中:使用小数
             - 参数:
                 - DecimalField.max_digits: 位数总数,包括小数点后的位数。 该值必须大于等于decimal_places.
                 - DecimalField.decimal_places: 小数点后的数字数量

            - 示例:
                 ```
                 money=models.DecimalField(
                     max_digits=7,
                     decimal_places=2,
                     default=0.0
                 )
                 ```
         6. FloatField()
             - 数据库类型:double
             - 编程语言中和数据库中都使用小数表示值
         7. EmailField()
             - 数据库类型:varchar
             - 编程语言和数据库中使用字符串
         8. IntegerField()
             - 数据库类型:int
             - 编程语言和数据库中使用整数
         9. URLField()
             - 数据库类型:varchar(200)
             - 编程语言和数据库中使用字符串
         10. ImageField()
             - 数据库类型:varchar(100)
             - 作用:在数据库中为了保存图片的路径
             - 编程语言和数据库中使用字符串
             - 示例:
                 ```
                 image=models.ImageField(
                     upload_to="static/images"
                 )
                 ```
             - upload_to:指定图片的上传路径
                 在后台上传时会自动的将文件保存在指定的目录下
         11. TextField()
             - 数据库类型:longtext
             - 作用:表示不定长的字符数据
         - 参考文档 <https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types>

    #### 字段选项
    4. FIELD_OPTIONS
         - 字段选项, 指定创建的列的额外的信息
         - 允许出现多个字段选项,多个选项之间使用,隔开
         1. primary_key
             - 如果设置为True,表示该列为主键,如果指定一个字段为主键,则此数库表不会创建id字段
         2. blank
             - 设置为True时,字段可以为空。设置为False时,字段是必须填写的。字符型字段CharField和TextField是用空字符串来存储空值的。 默认值是False。
         3. null
             - 如果设置为True,表示该列值允许为空。日期型、时间型和数字型字段不接受空字符串。所以设置IntegerField,DateTimeField型字段可以为空时,需要将blank,null均设为True。
             - 默认为False,如果此选项为False建议加入default选项来设置默认值


         4. default
             - 设置所在列的默认值,如果字段选项null=False建议添加此项
         5. db_index
             - 如果设置为True,表示为该列增加索引
         6. unique
             - 如果设置为True,表示该字段在数据库中的值必须是唯一(不能重复出现的)
         7. db_column
             - 指定列的名称,如果不指定的话则采用属性名作为列名
         8. verbose_name
             - 设置此字段在admin界面上的显示名称。
         - 示例:
             ```py
             # 创建一个属性,表示用户名称,长度30个字符,必须是唯一的,不能为空,添加索引

            name = models.CharField(max_length=30, unique=True, null=False, db_index=True)
             ```
    - 文档参见:
         - <https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-options>

    - 示例:



    #### 数据库迁移的错误处理方法
    - 当执行 `$ python3 manage.py makemigrations` 出现如下迁移错误时的处理方法
         - 错误信息
             ```
             $ python3 manage.py makemigrations
             You are trying to change the nullable field 'title' on book to non-nullable without a default; we can't do that (the database needs something to populate existing rows).
             Please select a fix:
             1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
             2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)
             3) Quit, and let me add a default in models.py
             Select an option:
             ```
         - 翻译为中文如下:
             ```
             $ python3 manage.py makemigrations
             您试图将图书上的可空字段“title”更改为非空字段(没有默认值);我们不能这样做(数据库需要填充现有行)。
             请选择修复:
             1)现在提供一次性默认值(将对所有现有行设置此列的空值)
             2)暂时忽略,让我自己处理空值的现有行(例如,因为您在以前的数据迁移中添加了RunPython或RunSQL操作来处理空值)
             3)退出,让我在models.py中添加一个默认值
             选择一个选项:
             ```
         - 错误原因
             - 当将如下代码
             ```
             class Book(models.Model):
                 title = models.CharField("书名", max_length=50, null=True)
             ```
             - 去掉 null=True 改为如下内容时会出现上述错误
             ```
             class Book(models.Model):
                 title = models.CharField("书名", max_length=50)
             ```
             - 原理是 此数据库的title 字段由原来的可以为NULL改为非NULL状态,意味着原来这个字段可以不填值,现在改为必须填定一个值,那填什么值呢?此时必须添加一个缺省值。
         - 处理方法:
             1. 选择1 手动给出一个缺省值,在生成 bookstore/migrations/000x_auto_xxxxxxxx_xxxx.py 文件时自动将输入的值添加到default参数中
             2. 暂时忽略,以后用其它的命令处理缺省值问题(不推荐)
             3. 退出当前生成迁移文件的过程,自己去修改models.py, 新增加一个`default=XXX` 的缺省值(推荐使用)

    - 数据库的迁移文件混乱的解决办法
         1. 删除 所有 migrations 里所有的 000?_XXXX.py (`__init__.py`除外)
         2. 删除 数据表
             - sql> drop database mywebdb;
         3. 重新创建 数据表
             - sql> create datebase mywebdb default charset...;
         4. 重新生成migrations里所有的 000?_XXXX.py
             - python3 manage.py makemigrations
         5. 重新更新数据库
             - python3 manage.py migrate


    ### 数据库的操作(CRUD操作)
    - CRUD是指在做计算处理时的增加(Create)、读取查询(Read)、更新(Update)和删除(Delete)

    #### 管理器对象
    - 每个继承自 models.Model 的模型类,都会有一个 objects 对象被同样继承下来。这个对象叫管理器对象
    - 数据库的增删改查可以通过模型的管理器实现
         ```
         class Entry(models.Model):
             ...
         Entry.objects.create(...) # 是管理器对象
         ```

    #### 创建数据对象
    - Django 使用一种直观的方式把数据库表中的数据表示成Python 对象
    - 创建数据中每一条记录就是创建一个数据对象
         1. Entry.objects.create(属性1=值1, 属性2=值1,...)
             - 成功: 返回创建好的实体对象
             - 失败: 抛出异常
         2. 创建 Entry 实体对象,并调用 save() 进行保存
             ```
             obj = Entry(属性=值,属性=值)
             obj.属性=值
             obj.save()
             无返回值,保存成功后,obj会被重新赋值
             ```
         3. 示例1:
             ```
             try:
                 abook = Book.objects.create(title='Python', pub='清华大学出版社')
                 print(abook)
             except:
                 print('创建对象失败')
             ```
         4. 示例2:
             ```
             try:
                 abook = Book(title='Python', pub='清华大学出版社')
                 abook.save
                 print(abook)
             except:
                 print('创建对象失败')
             ```
         5. 示例3:
             ```
             try:
                 abook = Book()
                 abook.title='Python'
                 abook.pub='清华大学出版社'
                 abook.save
                 print(abook)
             except:
                 print('创建对象失败')
             ```

        - 练习:
             - 使用以上三种方式,分别向Book和Publisher表中各增加三条数据

    #### Django shell 的使用
    - 在Django提供了一个交互式的操作项目叫 `Django Shell` 它能够在交互模式用项目工程的代码执行相应的操作
    - 利用 Django Shell 可以代替编写View的代码来进行直接操作
    - 在Django Shell 下只能进行简单的操作,不能运行远程调式
    - 启动 Django shell 显示IPython风格的交互界面如下:
         ```shell
         $ python3 manage.py shell
         manage.py shell
         Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
         Type 'copyright', 'credits' or 'license' for more information
         IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

        In [1]:
         In [2]: from bookstore import models
         In [3]: models.Book.objects.create(title="Python")
         Out[3]: <Book: Book object>
         In [4]: book = models.Book.objects.create(title='C++')
         In [4]: print(book)
         Book object
         ```

    - 练习:
         ```
         在 bookstore/models.py 应用中添加两个model类
         1. Book - 图书
             1. title - CharField 书名,非空,唯一
             2. pub - CharField 出版社,字符串,非空
             3. price - 图书价格,,
             4. market_price - 图书零售价
         2. Author - 作者
             1. name - CharField 姓名,非空,唯一,加索引
             2. age - IntegerField, 年龄,非空,缺省值为1
             3. email - EmailField, 邮箱,允许为空
         ```
         - 然后用Django Shell 添加如下数据
             - 图书信息
                 | 书名   | 定价 | 零售价 | 出版社      |
                 |---------|-------|--------------|----------------|
                 | Python  | 20.00 |        25.00 | 清华大学出版社 |
                 | Python3 | 60.00 |        65.00 | 清华大学出版社 |
                 | Django  | 70.00 |        75.00 | 清华大学出版社 |
                 | JQuery  | 90.00 |        85.00 | 机械工业出版社 |
                 | Linux   | 80.00 |        65.00 | 机械工业出版社 |
                 | Windows | 50.00 |        35.00 | 机械工业出版社 |
                 | HTML5   | 90.00 |       105.00 | 清华大学出版社 |
             - 作者信息:
                 | 姓名   | 年龄 | 邮箱 |
                 |-------|------|-----|
                 | 王老师 | 28 | wangwc@tedu.cn |
                 | 吕老师 | 31 | lvze@tedu.cn |
                 | 祁老师 | 30 | qitx@tedu.cn |
            


    ##### 查询数据
    - 数据库的查询需要使用管理器对象进行
    - 通过 Entry.objects 管理器方法调用查询接口
         | 方法 | 说明 |
         |-|-|
         | all() | 查询全部记录,返回QuerySet查询对象 |
         | get() | 查询符合条件的单一记录 |
         | filter() | 查询符合条件的多条记录 |
         | exclude() | 查询符合条件之外的全部记录 |
         ... |

    1. all()方法
         - 方法: all()
         - 用法: Entry.objects.all()
         - 作用: 查询Entry实体中所有的数据
             - 等同于
                 - select * from tabel
         - 返回值: QuerySet容器对象,内部存放Entry 实例
         - 示例:
             ```
             from bookstore import models
             books = models.Book.object.all()
             for book in books:
                 print("书名", book.title, '出版社:', book.pub)
             ```
    2. 在模型类中定义 `def __str__(self): ` 方法可以将自定义默认的字符串
         ```
         class Book(models.Model):
             title = ...
             def __str__(self):
                 return "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)
         ```

    3. 查询返回指定列(字典表示)
         - 方法: values('列1', '列2')
         - 用法: Entry.objects.values(...)
         - 作用: 查询部分列的数据并返回
             - select 列1,列2 from xxx
         - 返回值: QuerySet
             - 返回查询结果容器,容器内存字典,每个字典代表一条数据,
             - 格式为: {'列1': 值1, '列2': 值2}
         - 示例:
             ```
             from bookstore import models
             books = models.Book.objects.values("title", "pub")
             for book in books:
                 print("书名", book["title"], '出版社:', book['pub'])
                 print("book=", book)
             ```
    4. 查询返回指定列(元组表示)
         - 方法:values_list('列1','列2')
         - 用法:Entry.objects.values_list(...)
         - 作用:
             - 返回元组形式的查询结果
         - 返回值: QuerySet容器对象,内部存放 `元组`
             - 会将查询出来的数据封装到元组中,再封装到查询集合QuerySet中
         - 示例:
             ```
             from bookstore import models
             books = models.Book.objects.values_list("title", "pub")
             for book in books:
                 print("book=", book)  # ('Python', '清华大学出版社')...
             ```

    5. 排序查询
         - 方法:order_by
         - 用法:Entry.objects.order_by('-列','列')
         - 作用:
             - 与all()方法不同,它会用SQL 语句的ORDER BY 子句对查询结果进行根据某个字段选择性的进行排序
         - 说明:
             - 默认是按照升序排序,降序排序则需要在列前增加'-'表示

        - 示例:
             ```py
             from bookstore import models
             books = models.Book.objects.order_by("price")
             for book in books:
                 print("书名:", book.title, '价格:', book.price)
             ```

    6. 根据条件查询多条记录
         - 方法: filter(条件)
         - 语法:
             ```
             Entry.objects.filter(属性1=值1, 属性2=值2)
             ```
         - 返回值:
             - QuerySet容器对象,内部存放 Entry 实例
         - 说明:
             - 当多个属性在一起时为与关系,即当`Books.objects.filter(price=20, pub="清华大学出版社")` 返回价格为20 `且` 出版社为"清华大学出版社"的全部图书
         - 示例:
             ```
             # 查询书中出版社为"清华大学出版社"的图书
             from bookstore import models
             books = models.Book.objects.filter(pub="清华大学出版社")
             for book in books:
                 print("书名:", book.title)

            2. 查询Author实体中id为1并且isActive为True的
                 - authors=Author.objects.filter(id=1,isActive=True)
             ```

  • 相关阅读:
    hdu 2050 折线分割平面 递推
    hdu 2044 一只小蜜蜂 斐波那契数列 递推
    hdu 2018 母牛的故事 递推
    hdu 2084 数塔 dp 动态规划
    Linux 常用协议结构体及详解
    【ArcEngine入门与提高】Element(元素)、Annotation(注记)旋转
    AO总结10:MapControl控件
    esriControlsMousePointer 控制鼠标指针
    图解VS2010打包全过程(转)
    ArcEngine中打开各种数据源(WorkSpace)的连接(转)
  • 原文地址:https://www.cnblogs.com/shengjia/p/11190868.html
Copyright © 2020-2023  润新知