djando2.2-django ORM的概念、通过ORM操作数据库

一、django ORM

1. ORM的概念

  • django ORM的概念:

    ORM全称Object Relational Mapping(对象关系映射),django有了它,就能够通过python代码操作数据库(在底层转换为sql语句),免去sql语句的书写。

    但是,由于抽象程度较高,所以sql语句的执行效率比较低,因此,有些情况下,还是需要我们亲自书写sql语句。

  • 映射关系:

    ORM是通过以下对应关系,将python代码转换为sql语句的:

    python关系型数据库
    类属性字段
    对象记录
    对象的属性值记录的字段值

2. 模型类的书写

模型类就是用来映射数据库表的python类,必须写在models.py文件中,必须继承Model类。

比如下面的User类,就是一个模型类。

from django.db import models

class User(models.Model):
    id = models.AutoField(primary_key=True)
    username = models.CharField(max_length=20)
    password = models.IntegerField()

以上python代码等价于下面的MySQL代码:

BEGIN;
--
-- Create model User
--
CREATE TABLE `app01_user` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `username` varchar(20) NOT NULL, `password` integer NOT NULL);
COMMIT;

但此时,我们只是写下了python代码,数据库并没有任何变化。想要代码生效就要进行迁移。

3. 进行迁移

按照顺序在终端中执行以下两条命令:

  1. 生成迁移:

    python manage.py makemigrations
    

    它会检查models.py文件的修改,并生成一份迁移文件。该文件的路径为app文件夹\migrations\数字前缀_xxxxx.py

  2. 执行迁移:

    python manage.py migrate
    

    命令migrate只会为在 INSTALLED_APPS里注册了的app进行数据库迁移,将模型真正应用到数据库中。
    数据库中的表名为:app名称_模型类的小写形式

  • 查看对应SQL语句:
    执行以下命令,会打印对应的sql语句:

    python manage.py sqlmigrate app名称 迁移文件名的数字前缀
    

注意: 每次对模型类进行修改后,都要进行迁移操作!!!

4. Field类的常用选项

模型类中类属性都是一些Field类的实例对象,而这些Field类有以下选项(参数)是必须掌握的:

  • primary_key='布尔值'

    用来定义主键,如果我们在定义模型类时,没有定义主键对应的类属性,那么django会自动帮我们创建一个名为id的主键字段。

  • max_length='整数'
    指定字段宽度,CharField类必须传入该参数,否则会报错

  • verbose_name='别名'

    用来给字段取更加直白的别名(可以是中文),在django管理后台中,会以别名显示该字段。

  • null='布尔值':设置字段能否为空。

  • default='默认值':设置字段的默认值。

二、通过ORM操作数据库

ORM不能操作库,所以库的创建、修改和删除需要我们通过其他方法完成。

1. 创建数据表

就是模型类的书写,已经在上面讲过了。

2. 字段的增删改

  • 新增字段:

    先在模型类中新增类属性,然后执行迁移。迁移过程可能会提示:

    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) Quit, and let me add a default in models.py
    Select an option:
    

    这是因为没有给该字段设置默认值或允许该字段为空。可以:

    输入1回车,然后提供一个默认值给django:django会自动帮我们将该值设置为该字段的默认值;

    输入2:停止生成迁移文件,开发者到模型类中,设置默认值或设置允许为空后,再重新进行迁移。

  • 修改字段:

    直接修改模型类中的代码,然后进行迁移即可。

  • 删除字段:

    直接注释或删除类属性代码,然后进行迁移即可。

    如果删除模型类的类属性,执行完迁移后,对应字段的数据都会丢失。所以一定要小心谨慎,最好在迁移前检查一遍代码!!!

3. 记录的增删改查

对于数据的增删改查,通常都应该写在视图当中。如果只是测试一下,可以使用django的shell交互环境:

python manage.py shell

然后就可以导入需要的模块做测试了,下面的命令都可以在shell中允许,但是要先导入对应的模型类

  • 新建记录:

    方法一:

    模型类名.object.create(属性=,……)
    

    方法二:

    对象 = 模型类名(属性=,……)  # 生成对象
    对象.save()  # 保存到数据库
    
  • 查询单条记录:

    查询集 = 模型类名.object.filter(属性=,……)
    

    filter方法相当于sql的WHERE子句,该方法的返回值为查询集。查询集也称查询结果集、QuerySet,表示从数据库中获取的对象集合。因此,需要先取出一个对象之后,才能获取具体的值:

    对象 = 查询集.first()  # 获取第一个对象= 对象.属性  # 获取值
    
  • 查询所有记录:

    方法一:

    查询集 = 模型类名.object.filter()  # 不写任何条件
    

    方法二:

    查询集 = 模型类名.object.all()
    

    查询所有记录通常是为了展示给用户,可以使用django模板或jinja2模板的for语句实现,这些模板语句会在以后讲解。

  • 修改记录:

    方法一:

    查询集.update(属性=,……)
    

    update()会修改查询集中的所有记录。

    方法二:

    比如hugh是User模型类的一个对象,即数据库中的一条记录,则

    hugh.属性 = 值
    hugh.save()
    

    上述方法二,在修改字段值的时候,会将所有字段(包括没有修改过的字段)都更新一遍。因此,当记录的字段非常多的时候,效率会十分低。

  • 删除记录:

    模型类名.object.filter(属性=,……).delete()
    

    在实际开发中,我们通常都不会真的删除数据,而是进行逻辑删除。即,通过在表中增加一个is_delete的布尔类型字段,用来标识一条是否被数据了。将要被删除数据的is_delete改为1,意味着该字段“被删除”。

4. ORM建立表关系(外键字段的使用)

通常先建表,然后添加外键字段,所以我们先创建表的其他部分。

以图书、作者、出版社为例,假设:图书与作者是多对多关系、图书与出版社是多对一关系、作者与作者详情是一对一关系、作者与出版社没有关系:

from django.db import models

# Create your models here.

class Book(models.Model):
    """图书模型类"""
    title = models.CharField(max_length=128)
    # 价格字段,总共8位数字,其中小数部分占两位
    price = models.DecimalField(max_digits=8, decimal_places=2)

class Author(models.Model):
    """作者模型类"""
    name = models.CharField(max_length=32)

class Publisher(models.Model):
    """出版社模型类"""
    name = models.CharField(max_length=32)

class AuthorDetail(models.Model):
    """作者详情模型类"""
    addr = models.CharField(max_length=128)
  • 一对一(OneToOneField):

    作者与作者详情是一对一关系,外键建立在任何一方都可以,但推荐建立在查询频率比较高的一方

    class Author(models.Model):
        """作者模型类"""
        ……
        author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
    
    • 参数to用来指定关联的模型类(即关联的表),它默认跟作者详情的主键字段关联
    • 想要指定字段可以使用to_field='关联字段'参数,但是指定的关联字段必须设置unique=True
    • on_delete=models.CASCADE参数,用来设置外键记录的删除方法。当删除数据时,与之关联的数据也会被删除。还有其他on_delete参数选项,在下面有总结。
  • 一对多(ForeignKey):

    图书与出版社是多对一关系,外键建立在“多的”一方,即图书表中。

    class Book(models.Model):
        """图书模型类"""
    	……
        publisher = models.ForeignKey(to='Publisher', on_delete=models.CASCADE)
    
  • 多对多(ManyToManyField):

    图书与作者是多对多关系,按理来说,我们应该新建一张连接表,将对应关系保存在连接表中。但ORM做了优化,它会自动帮我们建立连接表,不需要我们再去手动建立关系表。外键字段建立在任何一方都可以,但是推荐建立在查询频率比较高的一方

    class Book(models.Model):
        """图书模型类"""
    	……
        author = models.ManyToManyField(to='author')
    

    多对多关系中,不用设置on_delete参数。

  • ForeignKeyOneToOneField生成的字段名称会自动加一个_id后缀,即publisher属性在数据库中的字段名为publisher_id

  • 在django1.x版本中,不需要传入on_delete参数,默认就是级联删除CASCADE

5. on_delete参数选项

on_delete参数删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING删除关联数据,什么也不做
on_delete=models.PROTECT删除关联数据,引发错误 ProtectedError
on_delete=models.SET_NULL删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
on_delete=models.SET_DEFAULT删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET(值或有返回值的可调用对象)删除关联数据,设置为传递给SET()的值
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花_城

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值