Python Django ORM

2023-05-16

一、ORM介绍


1.什么是ORM ?  ORM 全拼Object-Relation Mapping.

中文意为 对象-关系映射.

在MVC/MVT设计模式中的Model模块中都包括ORM
2.ORM优势
(1)只需要面向对象编程, 不需要面向数据库编写代码.

对数据库的操作都转化成对类属性和方法的操作.
不用编写各种数据库的sql语句.
(2)实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.

不在关注用的是mysql、oracle...等.
通过简单的配置就可以轻松更换数据库, 而不需要修改代码.
3.ORM劣势
相比较直接使用SQL语句操作数据库,有性能损失.
根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.
4.ORM和数据库关系:
在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常,一个模型(model)映射到一个数据库表.

基本情况:

每个模型都是一个Python类,它是django.db.models.Model的子类。

模型的每个属性都代表一个数据库字段。

综上所述,Django为您提供了一个自动生成的数据库访问API。

 

二、ORM用法

1.字段类型

属性名

  • 不允许使用python的保留关键字
  • 不允许使用mysql的保留关键字
  • 不允许使用连续的下划线,因为Django的查询语法就是连续的下划线
字段类型描述MySQL类型
AutoField自动增长的IntegerField, 不指定时Django会自动创建属性名为id的自动增长属性INT AUTO_INCREMENT
BigAutoField  
Binary二进制 
BooleanField布尔字段,值为True或False 
NullBooleanField支持Null、True、False三种值 
CharField(max_length=20)字符串,max_length表示最大字符个数VARCHAR(20)
TextFiled大文本字段,一般超过4000个字符时使用LONGTEXT
IntegerField整数
PositiveSmallIntegerField5个字节
SmallInteger6个字节
PositiveIntegerField10个字节
IntegerField11个字节
BigIntegerField20个字节
INT
DecimalField(max_digits=None, decimal_places=None)可以指定精度的十进制浮点数
  • 参数max_digits表示总位数
  • 参数decimal_places表示小数位数
DECIMAL
FloatField浮点数FLOAT
DateField([auto_now=False, auto_now_add=False])

日期

  • 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
  • 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
  • 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
DATE
DurationFieldint类型, python timedelta 实现 
DateTimeField日期时间,参数同DateFieldDATETIME
FileField上传文件字段,以二进制的形式 
ImageField

继承于FileField,对上传的内容进行校验,确保是有效的图片

 
Email邮箱 
URLURL 
GenericIPAddressIP地址 
UUIDUUID 

2.字段选项:

  • null:如果为True,表示允许为空,默认值是False
  • blank:如果为True,则该字段允许为空白,默认值是False    
  • 对比:null是数据库范畴的概念,blank是表单验证范畴的
  • db_column:字段的名称,如果未指定,则使用属性的名称(只限于数据库表中的名字,操作数据库还是类属性的名字)
  • db_index:若值为True, 则在表中会为此字段创建索引,默认值是False(为了优化查询速度 )
  • default:默认值,这可以是值或可调用对象。如果可调用,则每次创建新对象时都会调用它。
  • primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
  • unique:如果为True, 这个字段在表中必须有唯一值,这个值不能重复,默认值是False
  • 关系型字段类型:关联表中使用

注意:Django会自动为表创建主键字段

如果使用选项设置某属性为主键字段后,Django不会再创建自动增长的主键字段

3.关系字段类型

  • OneToOneField:一对一,将字段定义在任意一端中
  • ForeignKey:一对多,将字段定义在多的一端中
  • ManyToManyField:多对多,将字段定义在任意一端中
  • class Article(models.Model):
    
    
    class A(models.Model):
        oneToOne = models.OneToOneField(Article,related_name="one")
    
    class B(models.Model):
        foreign = models.ForeignKey(A,on_delete=models.CASCADE) # 级联删除
        # foreign = models.ForeignKey(A,on_delete=models.PROTECT) 
        # foreign = models.ForeignKey(A,on_delete=models.SET_NULL,null=True,blank=True) # 删除置空
        # foreign = models.ForeignKey(A,on_delete=models.SET_DEFAULT,default=0)
        # foreign = models.ForeignKey(A,on_delete=models.DO_NOTHING)
        # foreign = models.ForeignKey(A,on_delete=models.SET)
    
    class C(models.Model):
        manyToMany = models.ManyToManyField(B)

     

4. 元数据

class addressInfo(models.Model):
    address = models.CharField(max_length=200,null=True,blank=True,verbose_name="地址")
    pid = models.ForeignKey('self',null=True,blank=True,verbose_name="自关联")
    note = models.CharField(max_length=200,null=True,blank=True,verbose_name="说明")

    def __str__(self):
        return self.address

    class Meta:
        # 定义元数据
        db_table = 'address'
        ordering = 'pid' # 指定按照说明字段排序
        verbose_name = "省市县地址信息"
        verbose_name_plural = verbose_name
        # abstract = True    #抽象 ,不生成表
        permissions = (('定义好的权限','权限说明'),)
        unique_together = ('address','note')
        app_label = 'courses'   # 表前缀   courses_
        # db_tablespace  定义数据库表空间的名称

5.生成数据库的方法

在应用的models.py 下新增class对象后,执行命令:  python manage.py makemigrations 生成数据库迁移文件

然后执行 python manage.py migrate 将当前的migration文件内容持久化到数据库中

如果要删除一张表,要先删除 django_migrations表中的新增记录

然后删除migrations夹下的 py文件,最后删除models.py下的class

6.Django导入数据

通过脚本导入:   Course.objects.bulk_create( )

导入json 的方式: 执行命令: python manage.py loaddata data.json

 

三、Models API

假设有class A

A.objects.all();   #   select * from A

A.objects.get(id=1)  # select * from A where id=1

A.objects.filter(age__gte=20)  # select * from A where age>=20

A.objects.filter(id__in=[1,2,3]) # select * from A where id in (1,2,3)

A.objects.filter(name__icontains='A') # select * from A where name like '%A%'

A.objects.all()[:1]  # 

A.objects.all().order_by('-age') # select * from A order by age desc ;  

#查看执行的原生SQL
print(str(A.objects.filter(age__gte=20).order_by('-age').query))


# 返回新QuerySet API
A.objects.all().exclude(id=1)

A.objects.all().exclude(id=1).reverse()

A.objects.all().extra(select={"name":"nickname"})  # nickname as name 取别名

A.objects.all().only('nickname','age')   # 只查两个列

A.objects.all().select_related('B')    # 查询A时同时关联查询出B ,外键查询

A.objects.filter(age__lt=30).prefetch_related('C')  # 多对多关联查询



 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python Django ORM 的相关文章

随机推荐