• python的Web框架,Django的ORM,模型基础,MySQL连接配置及增删改查


    Django中的ORM简介

    ORM概念:对象关系映射(Object Relational Mapping,简称ORM):

    用面向对象的方式描述数据库,去操作数据库,甚至可以达到不用编写SQL语句就能够对数据库进行增删改查,进行各种操作。我们只需要对python的面向对象熟悉,就可以很清晰的知道各种数据之间的关系。

    django模型映射关系: 


    数据库连接配置

    Django支持主流的数据库,都有配置,在setting中配置即可,下面我们看下如何配置MySQL。

    db.sqlite3文件的说明

    db.sqlite3文件也是数据库文件,Django默认情况下,会配置这个文件,这个文件很小,很多单机、net的用的是这个 

    Django 连接MySQL的配置流程:

    • 安装 pymysql,用于python操作mysql数据库
    pip install pymysql
    • 创建数据库用户,需要有创建数据库权限的用户

    • 创建数据库

    #进入数据库,此命令用的root账户。正常是用数据库管理员给的数据库账号
    >>>(django) pyvip@Vip:~$ mysql -uroot -pqwe123
    
    #创建一个叫crm的数据库
    >>>mysql> create database crm;
    Query OK, 1 row affected (0.00 sec)
    • 修改setting配置,
     1 默认的是:'ENGINE': 'django.db.backends.sqlite3',需要修改为mysql
     2 DATABASES = {
     3     'default': {
     4         'ENGINE': 'django.db.backends.mysql',
     5         'NAME': 'crm',
     6         'USER': 'root',
     7         'PASSWORD': 'qwe123',
     8         'HOST': '127.0.0.1',
     9         #POST官方推荐的是字符串。
    10         'POST': '3306',
    11     }
    12 }
    • 修改项目文件夹(和setting.py文件所在的目录)下的__init__.py文件

    因为历史原因,python2用的模块是MySQLdb这个模块,所以需要如此写。

    #在__init__文件中配置
    1 import pymysql
    2 
    3 pymysql.install_as_MySQLdb()
    • 设置时区
    1  setting.py文件中设置时区
    2 
    3  TIME_ZONE = 'Asia/ShangHai'   #北京时间

    模型的创建与映射(激活)

    定义模型

    1. 模型类必须写在app下的models.py文件中。
    2. 模型如果需要映射到数据库,所在的app必须被安装。
    3. 一个数据表对应一个模型类,表中的字段,对应模型中的类属性。

    在models文件中创建模型:

     1  from django.db import models
     2     
     3     #必须继承'models.Model'
     4     class Students(models.Model):
     5     
     6         #模型会自动创建主键,djiano会自动创建一个字段为'id'的主键。
     7         id一般不用创建
     8         
     9         name = models.CharField(max_length=20)
    10         age = models.SmallIntegerField(default=0)
    11         sex = models.SmallIntegerField(default=1)
    12         qq = models.CharField(max_length=20, default='')
    13         phone = models.CharField(max_length=20, default='')
    14         c_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    15     
    16         #__str__代码是为了在ipython调试中方便查看数据,对数据库不造成任何影响,不用做数据库迁移
    17         def __str__(self):
    18             return '%s-%s' % (self.name, self.age)
        解析:
        CharField:字符字段,必须提供max_length这个参数,CharField的defaul最好不要给None。
        SmallIntegerField:int类型
        max_length:长度
        default:默认值,可以给'',如果不填,就是默认的。
        auto_now_add=True 在创建对象的时候,自动把当前时间记录下来。
        verbose_name:第一个位置参数,人类看的,如果没有提供这个字典,则直接使用它的变量
        
        qq、phone给的CharField不用SmallIntegerField类型的,是因为字符串更好操作,不容易出错。
    1. 每一个模型都是django.db.models.Model的子类(类的继承)。
    2. 每个模型都有许多的类变量,它会表示模型中的数据库字段。
    3. 每一个字段都由一个字段类的实例来表示。

    激活模型:

    1. 在项目中注册app
    1 INSTALLED_APPS = [
    2     'teacher.apps.TeacherConfig',
    3 ]
    1. 运行数据库迁移命令(一定要在项目根目录下) 告诉django,我们做了哪些数据库的更改
    'python manage.py makemigrations teacher'
    #如果不写teacher这个,则是运行INSTALLED_APPS下面所有注册的app
    
    >>> (django) pyvip@Vip:~/code/crm$ python manage.py makemigrations teacher
    Migrations for 'teacher':
      teacher/migrations/0001_initial.py
        - Create model Students

    运行成功后,会生成一个数据库迁移文件

    现在还没有真正的操作数据库

    sqlmigrate,从迁移获取SQL语句

    'python manage.py sqlmigrate teacher 0001'
    
    >>>(django) pyvip@Vip:~/code/crm$ python manage.py sqlmigrate teacher 0001
    BEGIN;
    -- 
    -- Create model Students
    --
    CREATE TABLE `teacher_students` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(20) NOT NULL, `age` smallint NOT NULL, `sex` smallint NOT NULL, `qq` varchar(20) NOT NULL, `phone` varchar(20) NOT NULL, `c_time` datetime(6) NOT NULL);
    COMMIT;
    
    #创建的表名是:appname_模型name.lower(小写)
    1. 运行migrate命令,使迁移生效
    #这里的teacher不写则默认生成所有的表
    'python manage.py migrate teacher'
    
    >>>(django) pyvip@Vip:~/code/crm$ python manage.py migrate teacher
    Operations to perform:
      Apply all migrations: teacher
    Running migrations:
      Applying teacher.0001_initial... OK
    
    #执行了teacher.0001_initial这个里面的tables。

    我们查看下是否创建了

    >>>mysql> show tables;
    +-------------------+
    | Tables_in_crm     |
    +-------------------+
    | django_migrations |
    | teacher_students  |
    +-------------------+
    2 rows in set (0.00 sec)
    
    这里生成了两张表:
        第一张表用来记录django的migrations
        第二张表是我们需要的数据表

    查看表结构:

    >>>mysql> desc teacher_students;
    +--------+-------------+------+-----+---------+----------------+
    | Field  | Type        | Null | Key | Default | Extra          |
    +--------+-------------+------+-----+---------+----------------+
    | id     | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name   | varchar(20) | NO   |     | NULL    |                |
    | age    | smallint(6) | NO   |     | NULL    |                |
    | sex    | smallint(6) | NO   |     | NULL    |                |
    | qq     | varchar(20) | NO   |     | NULL    |                |
    | phone  | varchar(20) | NO   |     | NULL    |                |
    | c_time | datetime(6) | NO   |     | NULL    |                |
    +--------+-------------+------+-----+---------+----------------+
    7 rows in set (0.00 sec)
    
    #此处表可以看到会根据我们的定义的模型来创建。

    MySQL数据库的增删改查

    django shell调试工具

    在进入之前建议安装ipython(pip安装),使用会更方便

    进入到调试工具
    
    >>>python manage.py shell

    增加

    #导入模型
    #导入我们需要调试的数据模型
    >>>from teacher.models import Students 

    查询模型中是否有数据

    objects是模型的一个属性(方法),object的管理器
    
    >>>Students.objects  
    <django.db.models.manager.Manager at 0xb2e0fe0c>

    查询模型中的所有的值

    >>>Students.objects.all()
    <QuerySet []>
    
    #此时我们还未添加数据,所以此处为空
    返回的值是QuerySet的一个查询集
    
    第一种方式,创建一条数据
    有default的不写默认是他自定的数据。
    >>>s1 = Students(name='小明', age=18, qq='123456')
    
    需要保存才可以操作数据库
    >>>s1.save()

    是否创建成功了呢,我们在MySQL中查看一下

    mysql> select * from teacher_students;
    +----+--------+-----+-----+--------+-------+----------------------------+
    | id | name   | age | sex | qq     | phone | c_time                     |
    +----+--------+-----+-----+--------+-------+----------------------------+
    |  1 | 小明   |  18 |   1 | 123456 |       | 2019-02-26 08:04:57.955584 |
    +----+--------+-----+-----+--------+-------+----------------------------+
    1 row in set (0.00 sec)
    
    #这里创建的时间一定是UTC时间,因为项目会运行在不同的时区,取出来的时候再转换成当前时间就好了。

     

    当前查看的all方式返回的是函数体类型的,不好查看,需要在模型代码中添加

    1 def __str__(self):
    2     return '%s-%s' % (self.name, self.age)

    再次查询的时候会变成格式化的样式

    >>>Students.objects.all()
    <QuerySet [<Students: 小明-18>]>
    第二种方式,创建一条数据,一条一条插入数据
    >>>s2 = Students()
    
    >>>s2.name = '小明'
    
    >>>s2.age = 18
    
    >>>s2.qq = '123456'
    第三种方式,创建一条数据,直接操作数据库
    >>>Students.objects.create(name='小明', age=18, qq='123456')
    <QuerySet: 小明-18>
    
    #返回查询集
    第四种方式,先查,查了再创建
    >>>Students.objects.get_or_create(name='小明')
    (<Students: 小明-18>, False)     
    
    #没有创建成功,数据存在返回查到的值
    第一个元素代表模型对象,bool值代表是否创建,False代表没有创建是查询的。

    查询

    all方法

    返回的是一个查询集,不是对象,没有操作数据库,可以查看到SQL语句

    >>>Students.objects.all()
    <QuerySet [<Students: 小明-18>, <Students: XiaoHong-16>, <Students: 王五-24>, <Students: 赵柳-22>]>
    
    #我们添加一些数据后,用于查询出来的结果

    查看all语句的背后的操作,查看sql语句

    >>>res = Students.objects.all()
    
    >>>print(res.query)
    SELECT `teacher_students`.`id`, `teacher_students`.`name`, `teacher_students`.`age`, `teacher_students`.`sex`, `teacher_students`.`qq`, `teacher_students`.`phone`, `teacher_students`.`c_time` FROM `teacher_students`
    
    #就相当于SQL语句: SELECT * FROM 'teacher_students'

    切片方式

    >>>res = Students.objects.all()
    
    >>>print(res[1:2].query)
    SELECT `teacher_students`.`id`, `teacher_students`.`name`, `teacher_students`.`age`, `teacher_students`.`sex`, `teacher_students`.`qq`, `teacher_students`.`phone`, `teacher_students`.`c_time` FROM `teacher_students`  LIMIT 1 OFFSET 1
    
    #通过切片的方式达到LIMIT的SQL语句
    get方法

    当我们的get匹配到多条数据的时候会报错。

    >>>Students.objects.get(name='小明')
     <Students: 小明-18>
    
    #如果给定的查询内容,可以匹配到多条数据,则会报错,get方法只能获取单挑且唯一的数据

    pk:参数中pk代表主键

    >>>Students.objects.get(pk=1)
    <QuerySet [<Students: 小明-18>]>
    
    #同样可以查询到,pk代表主键
    filter方法
    >>>res = Students.objects.filter(sex=1)
    
    >>>print(res.query)
    SELECT `teacher_students`.`id`, `teacher_students`.`name`, `teacher_students`.`age`, `teacher_students`.`sex`, `teacher_students`.`qq`, `teacher_students`.`phone`, `teacher_students`.`c_time` FROM `teacher_students` WHERE `teacher_students`.`sex` = 1

    修改

    get方法

    通过对象赋值的方法修改

    >>>s = Students.objects.get(name='小明')
    
    >>>s.age = 16
    
    >>>s.save()
    updata方法

    通过查询到的数据进行修改,可以修改多条数据

    >>>Students.objects.filter(name='小明').update(age=19)
    1
    #返回修改的条数

    删除

    delete方法

    指定删除,通过对象查到数据,再删除对象

    >>>s = Students.objects.get(pk=2)
    
    >>>s.delete()
    (1, ('teacher.Students': 1))
    
    #返回的是一个元祖:删除的数量,表的名称,删除数量

    删除多条

    >>>Students.objects.filter(sex=1).delete()
    (3, ('teacher.Students': 3))

    数据库应用到模型中

    views中的配置

    1 from teacher.models import Students
    2 
    3 def index(request):
    4     students = Students.objects.all()

    对应的html中配置

    1. 获取值的方式和字典的方式一样,不用再另外配置

    下一篇内容:模型属性,及数据库进阶查询,请点击这里

  • 相关阅读:
    《笨办法学python》 第14课手记
    《笨办法学Python》 第13课手记
    杭电2009----求数列的和
    杭电2008----数值统计
    杭电2007----平方和与立方和
    杭电2006----求奇数的乘积
    杭电2005----第几天?
    杭电2004---- 成绩转换
    杭电2003----求绝对值
    杭电2002----计算球体积
  • 原文地址:https://www.cnblogs.com/hua888/p/10442702.html
Copyright © 2020-2023  润新知