django框架基础-ORM基础-长期维护

 ###############    ORM介绍  ################

"""
ORM简介:
ORM 全拼Object-Relation Mapping.
中文意为 对象-关系映射.
在MVC/MVT设计模式中的Model模块中都包括ORM
在django里面主要是在models.py文件里面设计模型类,

ORM和数据库关系:
类--数据表
对象--数据行
属性--字段,理清了这三点,ORM就没有问题

ORM的优点:
1,不用编写各种数据库的sql语句,让软件开发人员专注于业务逻辑的处理,提高了开发效率。
2, 实现了数据模型和数据库之间的解耦,通过配置就可以更换数据库了 ORM的缺点: 1:根据对象的操作转换成SQL语句,根据查询的结果转化成对象,orm翻译成sql的过程 在映射过程中有性能损失. 如果一个公司对执行效率要求比较高,不如原生的sql效率高,但是web操作orm足够了, ORM能做的事情: 1,操作数据表,创建表,修改表,删除表, 2,操作数据行,数据的增删查改, 注意: 1,要自己创建数据库 2,使用mysql数据库需要配置,
"""

 

###################################################

"""
谈一谈你对ORM的理解:

ORM是“对象-关系-映射”的简称。
MVC或者MVC框架中包括一个重要的部分,就是ORM,
它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,
通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动

"""

 

###############    ORM使用mysql的基本配置    ################

# 配置使用mysql数据库
# 第一步:在项目目录下-项目文件夹下-settings文件中,
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'XXX',
        'USER': 'root',
        'PASSWORD': 'XXX',
        'HOST': 'localhost',
        'PORT':3306,
    }
}
# 第二步:在项目目录下-项目文件夹下-__init__文件中,替代默认的mysqldb,因为这个不支持Python3,
import pymysql
pymysql.install_as_MySQLdb()

#创建数据库
# ORM可以操作数据表,操作数据行,但是不能创建数据库,需要自己创建数据库,这是使用mysql的情况下
# 如果你使用SQLite,你不需要事先创建任何东西 —— 数据库文件将会在需要的时候自动创建。
cmd
mysql -uroot -p
create database XXXXX;
use django
show tables;

 

###############   ORM-字段类型    ################

"""
字段类型:

定义属性的格式:
属性名 = models.字段类型,定义属性时需要指定字段类型, 通过字段类型的参数指定选项

属性名定义的注意点:
1,不允许使用python的保留关键字
2,不允许使用mysql的保留关键字
3,不允许使用连续的下划线,因为Django的查询语法就是连续的下划线

常用字段类型:
1,AutoField:自动增长的IntegerField, 不指定时Django会自动创建属性名为id的自动增长属性
参数primary_key=True,必须填入。
2,BooleanField:布尔字段,值为True或False
3,NullBooleanField:支持Null、True、False三种值
4,CharField(max_length=20):字符串,
参数max_length表示最大字符个数,这个参数是必须的,
5,TextFiled:大文本字段,一般超过4000个字符时使用。新闻就可以使用这个字段,备注也可以,
6,IntegerField:整数,范围在10位,所以不能保存手机号,
7,DecimalField(max_digits=None, decimal_places=None):可以指定精度的十进制浮点数,这个精度比float要高,float存进计算机和取出来,是有差异的,
参数max_digits表示总位数
参数decimal_places表示小数位数
8,FloatField():浮点数 
9,DateField[auto_now=False, auto_now_add=False]):日期,日期格式  YYYY-MM-DD,
参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
参数auto_now_add和auto_now是相互排斥的,组合将会发生错误,两个参数不是必须的,
10,TimeField:参数和DateField一样
11,DateTimeField:日期时间,参数同DateField,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],
12,FileField:上传文件字段,以二进制的形式
13,ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片

"""

实例:

from django.db import models
class Test(models.Model):
    id = models.AutoField(primary_key=True)
    isnum=models.BooleanField()
    # isnum2=models.NullBooleanField
    name = models.CharField(max_length=20,unique=True)
    text=models.TextField()
    age=models.IntegerField()
    price=models.DecimalField(max_digits=10,decimal_places=2)
    # price2 =models.FloatField(max_digits=10,decimal_places=2) 
    create_time=models.DateField(auto_now_add=True)  
    update_time = models.DateField(auto_now=True)  
    time=models.TimeField()  
    data_time=models.DateTimeField(null=False)  
    file=models.FileField()  
    image=models.ImageField()  

如何设置一个带有枚举值的字典?

gender_choices = (
        (1, ''),
        (2, ''),
    )
gender = models.IntegerField(verbose_name='性别', choices=gender_choices, default=1)

 

###############   ORM-字段选项    ###############

'''
字段选项:
1,null:如果为True,表示允许为空,默认值是False
2,blank:如果为True,则该字段允许为空白,默认值是False    
对比:null是数据库范畴的概念,blank是表单验证范畴的
3,db_column:字段的名称,如果未指定,则使用属性的名称(只限于数据库表中的名字,操作数据库还是类属性的名字)
4,db_index:若值为True, 则在表中会为此字段创建索引,默认值是False(为了优化查询速度 )
5,default:默认值,这可以是值或可调用对象。如果可调用,则每次创建新对象时都会调用它。
6,primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
7,unique:如果为True, 这个字段在表中必须有唯一值,这个值不能重复,默认值是False
8,时间字段独有,DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
配置上auto_now=True,每次更新数据记录的时候会更新该字段
# 注意:default和blank不影响表的结构,不需要做迁移,其他的都要迁移,

注意:Django会自动为表创建主键字段
如果使用选项设置某属性为主键字段后,Django不会再创建自动增长的主键字段
默认创建的主键字段为id,可以使用pk代替,pk全拼为primary key

"""

 

###############   ORM-字段选项    ###############

解释blank和null

网上介绍这两者区别和联系的博客大部分都只说明了两点:

blank用于表单的认证,被设为blank=False(默认为False)的字段在填写表单时不能为空。----这是限制django-admin的,不能是空,

null用于规定数据库中的列的非空性,被设为null
=False(默认为False)的字段在数据库中对应的列不能为空 ------这是限制数据库,不能为空,
(用SQL来说明就是为该列添加了NOT NULL的约束)。

所以一般是这两个是成对出现的

 

###############   ORM-关系字段类型    ################

"""
关系字段类型:
关系型数据库的关系包括三种类型:
1,ForeignKey:一对多,将字段定义在多的一端中
参数:
to 设置要关联的表
to_field 设置要关联的表的字段
related_name 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。
related_query_name  反向查询操作时,使用的连接前缀,用于替换表名。
on_delete 当删除关联表中的数据时,当前表与其关联的行的行为。
#   on_delete=models.CASCADE 删除关联数据,与之关联也删除
#   on_delete=models.SET_NULL 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
db_constraint 是否在数据库中创建外键约束,默认为True。

2,OneToOneField:一对一,将字段定义在任意一端中
参数:
to 设置要关联的表
to_field 设置要关联的表的字段
on_delete 当删除关联表中的数据时,当前表与其关联的行的行为。

3,ManyToManyField:多对多,将字段定义在任意一端中
用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系。
参数:
to 设置要关联的表
related_name 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。
related_query_name  反向查询操作时,使用的连接前缀,用于替换表名。
symmetrical 仅用于多对多自关联时,指定内部是否创建反向操作的字段。默认为True。
through 在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。
但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。
through_fields  设置关联的字段。
db_table 默认创建第三张表时,数据库中表的名称。

"""
 

 

 

###############  ORM-元信息    ################

"""
元信息
ORM对应的类里面包含另一个Meta类,而Meta类封装了一些数据库的信息。
主要字段如下:
db_table ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。
工作中一定要指定表名,否则改动了程序app的名字,迁移的时候就会出问题,
index_together 联合索引。
unique_together 联合唯一索引。
ordering 指定默认按什么字段排序。只有设置了该属性,我们查询到的结果才可以被reverse()。
verbose_name 指定在admin管理界面中显示中文;verbose_name表示单数形式的显示,
verbose_name_plural 表示复数形式的显示;中文的单数和复数一般不作区别。


如果你定义了一个模型类,但是你并不想让这个模型类生成数据表,
仅仅是想让其他的类来继承这个类,那么你就需要定义这样一个元数据:
abstract=True。定义完之后这个类就成了基类,不会再数据库中生成数据表。

"""
from django.db import models

class Ox(models.Model):
    name = models.CharField()
    class Meta:         # 注意,是模型的子类,要缩进!
        abstract=True

 

###############   使用ORM创建表    ################

from django.db import models


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 与AuthorDetail建立一对一的关系
    authorDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)
    # models.CASCADE     删除关联数据,与之关联也删除


class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)
    # 一个作者对应一个作者详情,
    # 为什么这么做,因为作者表用的非常的频繁,每一次查的时候都要全表查,数据量大,但是用到的字段不多,
    # 所以把常用的字段抽离出来,比如列表页和详情页,这些都是需要分离的,为了更快的查询,


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        # 返回出版社的名称
        return self.name


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)

    # 与Publish建立一对多的关系,外键字段建立在多的一方
    publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors = models.ManyToManyField(to='Author', )

    def __str__(self):
        return self.title

 

 

执行命令:

# 执行命令,这样表就创建了
python manage.py makemigrations   #把改动记录到文件中,
python manage.py migrate  #迁移

# 在django中的ORM操作数据库表:
# 删除数据表,注释掉整个建表的类,
# 执行语句,这样就删除表了,
python manage.py makemigrations
python manage.py migrate

# 修改字段一样,修改表字段,
# 执行语句,
python manage.py makemigrations
python manage.py migrate

 

###############   使用ORM创建表    ################

###############   使用ORM创建表    ################

 

###############   使用ORM创建表    ################

posted @ 2019-12-13 11:44  技术改变命运Andy  阅读(247)  评论(0编辑  收藏  举报