Django中使用ORM

一、ORM概念

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

ORM在业务逻辑层和数据库层之间充当了桥梁的作用。

二、Django中的ORM

django中使用Mysql数据库

DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "你的数据库名称", # 需要自己手动创建数据库
"USER": "数据库用户名",
"PASSWORD": "数据库密码",
"HOST": "数据库IP",
"POST": 3306
}
}

2. 在与Django项目同名的目录下的__init__.py文件中写如下代码,告诉Django使用pymysql模块连接MySQL数据库:

import pymysql

pymysql.install_as_MySQLdb()

注:数据库迁移的时候出现一个警告

WARNINGS:
?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion,
by escalating warnings into errors. It is strongly recommended you activate it.

在配置中多加一个OPTIONS参数:Django官网解释

'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},

Model

在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常,一个模型(model)映射到一个数据库表。

基本情况:

  • 每个模型都是一个Python类,它是django.db.models.Model的子类。
  • 模型的每个属性都代表一个数据库字段。
  • 综上所述,Django为您提供了一个自动生成的数据库访问API,详询官方文档链接

Django中使用ORM

ORM操作

    • 增:
      • models.Tb1.objects.create(c1='xx', c2='oo')   # 增加一条数据,可以接受字典类型数据 **kwargs
      • orm批量创建数据
        • bulk_create(objs)
        • objs=[models.Book(title="图书{}".format(i+15)) for i in range(100)]
        • models.Book.objects.bulk_create(objs)
    • 删:
      • models.Tb1.objects.filter(name='seven').delete()  # 删除指定条件的数据
    • 改:
      • models.Tb1.objects.filter(name='seven').update(gender='0')   # 将指定条件的数据更新,均支持 **kwargs

必知必会13条

  • 1、all() 查询所有数据
  • 2、get(**kwargs) 获取一个对象 如果查询没有或者多个 就报错
  • 3、filter(**kwargs) 查询所有满足条件的对象
  • 4、exclude(**kwargs): 查询所有不满足条件的对象
  • 5、values(*field): 不写参数 取对象的所有字段数据 指定参数 取对象指定字段的数据
  • 6、values_list(*field): 不写参数 取对象的所有字段数据,元组形式 ,指定参数 取对象指定字段的参数
  • 7、order_by(*field): 按照指定字段排序 默认升序 ,加负号降序,可以多字段排序
  • 8、reverse(): 对已经排序的QuerySet进行反向排序。
  • 9、distinct() 去重,从返回结果中剔除重复纪录
  • 10、count(): 计数 对QuerySet的对象进行计数
  • 11、first(): 取QuerySet中的第一元素
  • 12、last(): 返回最后一条记录
  • 13、exists(): 如果QuerySet包含数据,就返回True,否则返回False

单表查询双下划线模糊查询

    • 1、gte 大于等于;lte小于等于
    • 2、in 在xx之中
      ret = models.Person.objects.filter(id__in=[1,3,5,7,9,]) 获取id等于1,3,5,7,9的对象,id没有7,9不会报错
    • 3、contains 包含,对大小写敏感;icontains 包含,对大小写不敏感
      models.Person.objects.filter(name__contains='du') 获取name字段包含“du”的,对大小写敏感
    • 4、range 范围
      models.Person.objects.filter(id__range=[1,5]) 获取id等于1到5的对象
    • 5、startswith 以xx开头,istartswith 开头.不区分大小写, endswith结尾, iendswith结尾不区分大小写

锁和事务

1. 锁

select_for_update(nowait=False, skip_locked=False)

返回一个锁住行直到事务结束的查询集,如果数据库支持,它将生成一个 SELECT ... FOR UPDATE 语句。

举个例子:

entries = Entry.objects.select_for_update().filter(author=request.user)

所有匹配的行将被锁定,直到事务结束。这意味着可以通过锁防止数据被其它事务修改。

一般情况下如果其他事务锁定了相关行,那么本查询将被阻塞,直到锁被释放。 如果这不想要使查询阻塞的话,使用select_for_update(nowait=True)。 如果其它事务持有冲突的锁, 那么查询将引发 DatabaseError 异常。你也可以使用select_for_update(skip_locked=True)忽略锁定的行。 nowait和skip_locked是互斥的,同时设置会导致ValueError。

目前,postgresql,oracle和mysql数据库后端支持select_for_update()。 但是,MySQL不支持nowait和skip_locked参数。

使用不支持这些选项的数据库后端(如MySQL)将nowait=True或skip_locked=True转换为select_for_update()将导致抛出DatabaseError异常,这可以防止代码意外终止。

2. 事务

import os

if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
import django
django.setup() import datetime
from app01 import models try:
from django.db import transaction
with transaction.atomic():
new_publisher = models.Publisher.objects.create(name="火星出版社")
models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10)
# 指定一个不存在的出版社id
except Exception as e:
print(str(e))
上一篇:Django的日常-模型层(2)


下一篇:golang time and duration