美文网首页
Django框架(六):Django模型系统 ① 模型基础

Django框架(六):Django模型系统 ① 模型基础

作者: 加州旅馆_6741 | 来源:发表于2019-03-30 10:58 被阅读0次

1.Django 的 ORM 介绍

ORM:对象关系映射 (英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
作用:在实际开发中不方便直接对数据库进行sql语句操作,所以我们将sql数据库中的表,直接映射成python中的对象,对对象进行增删改查的操作。

2.数据库配置

  • 安装pymysql
pip install pymysql -i https://pypi.douban.com/simple
  • 修改项目目录下的__init__.py文件
import pymysql
pymysql.install_as_MySQLdb()
  • 手动创建一个当前项目的空的数据库,准备一个有创建数据库权限的用户
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.29 sec)

mysql> create database crm charset=utf8;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| crm                |
| mydb               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)
  • 配置settings.py文件
DATABASES = {
    'default': {
        ##定义引擎 'ENGINE': 'django.db.backends.sqlite3', ## python默认的小型文件数据库
        ##定义文件 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql', ## 定义mysql引擎
        'NAME': 'crm', ## 数据库名
        'USER': 'admin',
        'PASSWORD': 'Root110qwe',
        'HOST':'127.0.0.1',
        'PORT':'3306',
    }
}

3.模型的创建与映射

模型:什么是模型,模型就是django.db.models.Model的一个子类

模型类对应数据库中的数据表,类属性对应的表字段名

a.创建模型
  • 模型定义在app文件夹下的models.py文件中
from django.db import models

# Create your models here.

class Students (models.Model): # 一个类代表一个数据表
    id = models.AutoField(primary_key=True) ##创建一个可以自动生成的主键,这条也可以不写,Django中会自动生成主键
    name = models.CharField(verbose_name='姓名',
                            max_length=20)   ##创建字符类型字段,最大长度为20,设置提示信息'姓名'
                                            ### max_length为CharField的必须参数
    age = models.SmallIntegerField(verbose_name='年龄',null=True) ##创建值可以为null的小整型字段,
    sex = models.SmallIntegerField(default=1)   ##创建缺省值为1的小整型字段
    qq = models.CharField(max_length=20,null=True)
    phone = models.CharField(max_length=20,null=True)
   c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)  ##创建日期时间类型字段,自动创建当前时间
b.激活模型
  • 注册应用
  • 创建迁移
    什么叫迁移:"在django中对数据库中的结构有任何改变都叫做迁移"
  1. 这条命令会在app目录的migrations目录下创建一个迁移文件
(crm) pyvip@VIP:~/projects/crm$ python manage.py makemigrations teacher
Migrations for 'teacher':
  teacher/migrations/0001_initial.py
    - Create model Students
  1. 如果要看这个迁移文件会产生什么样的SQL语句,可以执行下面这条命令
(crm) pyvip@VIP:~/projects/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 NULL, `sex` smallint NOT NULL, `qq` varchar(20) NULL, `phone` varchar(20) NULL, `c_time` datetime(6) NOT NULL);
COMMIT;
  1. 执行迁移文件操作数据库,将对模型的改动应用到数据库(底层就是执行了SQL语句)
(crm) pyvip@VIP:~/projects/crm$ python manage.py migrate teacher
Operations to perform:
  Apply all migrations: teacher
Running migrations:
  Applying teacher.0001_initial... OK

查看所创建的表

mysql> show tables;
+-------------------+
| Tables_in_crm     |
+-------------------+
| django_migrations |
| teacher_students  |
+-------------------+
2 rows in set (0.00 sec)

teacher_students就是刚才创建的数据表,表名 = appname_模型类
django_migrations是所有的迁移记录数据表,里面记录了所有的迁移记录

python manage.py migrate appname 这条命令执行的操作:

  • 在app中查找迁移文件,并且去django_migrations表中查找,如果有没有执行的迁移文件就去执行
  • 执行迁移生成的SQL语句
  • 如果成功,会在django_migrations表中增加一条记录

4.简单的数据的增删改查

在Django模型中,一个类代表一张数据表,一个类的实例代表一条数据

  • Django调试环境
(crm) pyvip@VIP:~/projects/crm$ python manage.py shell
Python 3.6.6 (default, Sep 12 2018, 18:26:19) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

增加有几种方法
a. 第一种方式

In [1]: from teacher.models import Students            #导入这个类                            

In [2]: Students.objects.all()        #查询这个数据表的所有数据                                             
Out[2]: <QuerySet []>      #当前数据为空

In [3]: s = Students()           #创建这个类的实例,即一条数据                                                  

In [4]: s                                                             
Out[4]: <Students: Students object (None)>    # 这条数据为空             

In [5]: s.name = '小米'                 #为这条数据的一个字段赋值                                           

In [6]: s.age = 18                                                                 

In [7]: s.save()                          #每次赋值之后必须要保存,否则数据不会上传到数据库中                                         

In [8]: Students.objects.all()                                                     
Out[8]: <QuerySet [<Students: Students object (1)>]>        #查询到一条数据

然后在数据库中就能查询到这条数据

mysql> select * from teacher_students;
+----+--------+------+-----+------+-------+----------------------------+
| id | name   | age  | sex | qq   | phone | c_time                     |
+----+--------+------+-----+------+-------+----------------------------+
|  1 | 小米   |   18 |   1 | NULL | NULL  | 2019-03-27 18:17:46.167806 |
+----+--------+------+-----+------+-------+----------------------------+
1 row in set (0.00 sec)

b. 第二种方式

In [10]: stu = Students.objects.create(name='小李',age=22)        #直接用create方法直接创建         

In [11]: stu.name                                                                  
Out[11]: '小李'

In [12]: stu.id                                                                    
Out[12]: 3

  • 删除
In [13]: stu.delete()                                                              
Out[13]: (1, {'teacher.Students': 1})

改一条数据

In [14]: stu.age = 33                                                              

In [15]: stu.save()          

改所有的数据

In [27]: Students.objects.all().update(age=15)                                     
Out[27]: 3
  • 查询
    查一条数据和所有的数据
In [16]: Students.objects.all()                 #查所有的数据                                   
Out[16]: <QuerySet [<Students: Students object (1)>, <Students: Students object (2)>, <Students: Students object (4)>]>

In [17]: res = Students.objects.all()                                              

In [18]: 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`

In [19]: Students.objects.get(pk=1)          #查询主键为1的一条数据,如果查询到多条数据就报错,主键默认参数为`pk`                                      
Out[19]: <Students: Students object (1)>

首先我们看一下这几条语句,什么是objects,什么是QuerySet,什么是all()方法

  • objects是一个Manager类型的对象,定义在from django.db import models中,是默认生成的,也就是objects = Modes.Manage(),他提供一个数据库和模型对象交互的接口(api)。Students.objects.all()翻译过来就是Students类通过Manager管理器,用all接口返回一个QuerySet对象

在res = Students.objects.get()或者res = Students.objects.all()中

  • Students是类名,就是你在model中创建的类
  • objects是django默认的管理器对象,帮你完成各种操作。
  • get()或者all()是API,一种内置函数,不同的操作调用不同的API就可以了。
  • res通过all()得到的就是queryset()对象,也就是查询对象的集合。

QuerySet是惰性的,只有调用的时候才会执行

带条件查询
In [25]: res = Students.objects.filter(name='小米',age=18)                         

In [26]: res                                                                       
Out[26]: <QuerySet [<Students: Students object (1)>]>

补充:模型元数据

我们要定义模型的一些属性,比如排序选项(attr:~Options.ordering),数据库表名(db_table),或是人可读的单复数名(verbose_name和verbose_name_plural)时,必须要用到元数据,内部使用Meta类来给模型赋予元型态数据

实例:

from django.db import models

class Ox(models.Model):
    horn_length = models.IntegerField()

    class Meta:
        ordering = ["horn_length"]    #默认按horn_length字段的升序排序
        verbose_name_plural = "oxen"    #设置模型对象的复数名称

相关文章

网友评论

      本文标题:Django框架(六):Django模型系统 ① 模型基础

      本文链接:https://www.haomeiwen.com/subject/xnsxbqtx.html