Django(四)数据库

本文详细介绍了Django中的ORM框架,包括数据库配置、模型定义、数据库操作(增删改查)、QuerySet的高级用法以及性能优化策略。通过实例展示了如何创建和管理数据库表,以及如何进行多表查询、关联关系处理和聚合分组查询。最后总结了多表查询的方法和表创建的注意事项。
摘要由CSDN通过智能技术生成

一、数据库框架

数据库框架是数据库的抽象层,也称为对象关系映射(Object-Relational Mapper, ORM),它将高层的面向对象操作转换成低层的数据库指令,比起直接操作数据库引擎,ORM极大的提高了易用性。这种转换会带来一定的性能损耗,但ORM对生产效率的提升远远超过这一丁点儿性能降低。
Django中内置的SQLAlchemy ORM就是一个很好的数据库框架,它为多种关系型数据库引擎提供抽象层,比如MySQL, Postgres,SQLite,并且使用相同的面向对象接口。因此,使用SQLAlchemy ORM,不仅能极大的提高生产力,而且可以方便的在多种数据库之间迁移。

二、配置数据库

我们可以在项目文件夹的settins.py中配置数据库引擎。
Django默认使用sqlite:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',  # sqlite引擎
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

如果要要使用mysql, 需要进行如下配置:
1 编辑项目文件夹下的settings.py :

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.mysql',  # mysql引擎
        'NAME': 'BookManagement',    
        # 数据库名称, 需要通过命令‘CREATE DATABASE BookManagement’在mysql命令窗口中提前创建
        'USER': 'root',   #你的数据库用户名
        'PASSWORD': '***', #你的数据库密码
        'HOST': '', #你的数据库主机,留空默认为localhost
        'PORT': '3306', #你的数据库端口
    }
}

2 编辑项目文件夹下的__init__.py :
由于mysql在Django中默认驱动是MySQLdb, 而该驱动不适用于python3, 因此,我们需要更改驱动为PyMySQL

import pymysql

pymysql.install_as_MySQLdb()

3 显示SQL语句
前面我们说了ORM将高层的面向对象的操作,转换为低层的SQL语句,如果想在终端打印对应的SQL语句,可以在setting.py中加上日志记录:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

三、模型

在ORM中,用模型(Model)表示数据库中一张表。模型的具体实现是一个Python类,类中的属性对应数据库表中的字段,这个类的实例化对象,对应表中的一条记录。
总结:类 –> 表; 类属性 –> 表字段; 类实例 –> 表记录

定义模型

定义模型就是定义一个python类,以创建一个图书管理系统为例,基本形式如下:

from django.db import models

class Publish(models.Model):
    name = models.CharField(max_length=60)
    addr = models.CharField(max_length=60)

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name


class Book(models.Model):
    name = models.CharField(max_length=60)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    publish = models.ForeignKey(Publish)
    # 定义书与出版社的多对一关系
    # 默认绑定到Publish表中的主键字段
    authors = models.ManyToManyField(Author)
    # 定义书与作者的多对多关系,ORM将自动创建多对多关系的第三张表

说明:
1. 定义完模型后,或者修改了模型后,要执行数据库迁移操作:
python manage.py makemigrations
python manage.py migrate
执行完命令后,查看数据库的表目录,可以看到上述表格成功创建:
这里写图片描述
2. 上述模型中都没有设置主键,在完成上迁移操作后,orm会自动创建主键。
3. orm会自动将Book表中的关联字段publish, 在数据库中存为publish_id, 所以不要画蛇添足自己命名为publish_id,否则你在数据库中看到的是publish_id_id
4. 外键引用的主表要么在子表前创建,要么使用字符串形式指定,否则子表找不到主表。
5. 如果我们实例化一个Book对象,book_obj, 那么通过book_obj.publish得到的是publish_id对应的那个Publish对象。这是ORM作的设定,原因很简单,如果通过book_obj.publish得到只是一个publish_id,对我们并没有多大用。
6. 虽然不是强制的,但是建议在每个类中定义__str__方法(或__repr__方法),这样当我们打印对象时,可以显示具有可读性的字符串信息,方便调试。
7. 只要在一张表中定义了多对多关系,orm会自动创建实现多对多关系的第三张表。当然,你也可以手动创建,如下:

class BookToAuthor(models.Model):
    # 手动创建书与作者的多对多关系的第三张表
    book = models.ForeignKey(Book)
    author = models.ForeignKey(Author)

还是不建议手动创建,一是麻烦,而是后面我在执行删除记录的操作时,提示找不到第三关联表,可能是我表名命名问题,猜测应该将第三张表命名为Book_authors的格式,这样才能和orm自动创建的第三张表同名,未验证。。。

字段类型

类型名 Python类型 说明
IntegerField int 普通整数,通常是32位,-2147483648 to 2147483647
SmallIntegerField int 小整数,一般是16位,-32768 to 32767
BigIntegerField int/long 64位的整数,-9223372036854775808 to 9223372036854775807
FloatField float 浮点数
DecimalField(max_digits=None, decimal_places=None decimal.Decimal 定点数,精度更高;要求指定位数和小数点精度。
CharField(max_length=None) str 字符串;要求指定最大长度
TextField str 变长字符串
BooleanField bool 布尔值
DateField datetime.date 日期,比如:2017-08-25
DateTimeField datetime.datetime 日期和时间
BinaryField str 二进制

更多类型请参考官网 field types

关系字段

字段 说明
ForeignKey(othermodel) 多对一关系,需要指定关系表
ManyToManyField(othermodel) 多对多关系,需要指定关系表
OneToOneField(othermodel) 一对一关系,需要指定关系表

字段选项

选项 说明
primary_key 如果设置primary_key=True, 这列就是表的主键;如果不指定,Django会自动添加一个AutoField字段来盛放主键,所以我们一般无需设定主键。
unique 如果设置unique=True, 这列不允许出现重复的值
db_index 如果设置db_index=True, 为这列创建索引,提升查询效率
null 如果设置null=True, 这列允许使用空值;如果新增了字段,建议设置该选项,因为新增字段之前的记录没有该字段
default 为这列定义默认值;如果新增了字段,建议设置该选项,因为新增字段之前的记录没有该字段
related_name 在一对多关系多所在的表中定义反向引用;这样在一所在的表中反向查询多所在的表时,直接用这个字段就行了,可以替代下面要讲到的_set反向查询

更多选项请参考官网 filed options

四、数据库的操作

下面通过python shell来演示数据库的操作。在终端切换到项目根目录下,输入命令python manage.py shell进入shell操作环境:

增删改查

1 创建记录

方式一:实例化

>>> from app.models import Author #导入模型
>>> a = Author(name="张三")  # 实例化
>>> a.save()  # 插入记录
>>> print(a)
张三

方式二:create()工厂函数

>>> Author.objects.create(name='李四')
<Author: 李四>

通过get_or_create()创建记录,这种方法可以防止重复(速度稍慢,因为会先查询数据库),它返回一个元组,第一个是实例对象(记录),创建成功返回True,已存在则返回False,不执行创建。

>>> Author.objects.get_or_create(name='李四')
(<Author: 李四>, False)
2 查询记录

1 Author.objects.all()查询所有

>>> Author.objects.all()
<QuerySet [<
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值