Python之Django的Model详解
一、创建数据库
创建数据库
进入数据库: mysql -uroot -p
创建数据库: CREATE DATABASE test1 CHARSET=utf8;
连接数据库
虚拟环境中安装数据库模块:pip install pymysql
在Django_model[项目名]/Django_model/__init__py中书写:
import pymysql
pymysql.install_as_MySQLdb()
修改settings.py文件
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # postgresql / mysql / sqlite3 / oracle
'NAME': 'test1', # 数据库名
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'localhost', # 本地:localhost
'PORT': '3306', # 默认端口:3306
}
}
二、Model使用流程
- 创建应用python manage.py startapp [应用名]
- settings.py中的 INSTALLED_APPS = [] 添加应用
- models.py定义模型类
- 生成迁移python manage.py makemigrations
- 执行迁移python manage.py migrate
- 使用模型
三、Model字段
字段类型
AutoField: 无需指定,自增长id
BooleanField: Boolean类型,默认Flase;表单控件: CheckboxInput
NullBooleanField: Boolean类型, 支持None, True, FalseCharField(max_length=字段长度20): 字符串
IntegerField: 整数
FloatField: 浮点数
DateField: datetime.date实例的日期
TimeField: datetime.time实例的时间
DecimalField(max_digits=位数总数None, decimal_places=小数点后的数字位数None): Decimal的十进制浮点数
DateTimeField([auto_now=修改时间戳False, auto_now_add=创建时间戳False]): datetime.datetime实例的日期和时间; 表单控件: TextInput + 日历控件FileField: 上传文件(非路径)
mageField:上传image
字段选项
- null: True:允许None; 默认:False
- blank: True:允许空白; 默认:False
- db_column: 字段名; 默认:属性名
- db_index: True:创建索引; 默认:False
- default: 默认值
- primary_key: True:主键
- unique: True:值唯一
关系
- ForeignKey: 一对多, 将该属性定义到多的那一端
- OneToOneField: 一对一, 将该属性定义到任一端
- ManyToManyField: 多对多, 将该属性定义到两端
- 递归关联(自连接/自关联): 一对多, 用一张表存储所有信息
访问
BookshelfInfo
BookInfo
bookshelf = models.ForeignKey(Bookshelf)
用一访问多:
对象.模型类_set
bookshelf.bookinfo_set
用一访问一:
对象.模型类
book.bookshelfinfo
访问id:
对象.属性_id
book.bookshelf_id
使用例子:
bookshelf = Bookshelf.objects.get(pk=1) # 查询指定书架
bookshelf.bookinfo_set.all() # 获取该书架所有的书信息
创建表结构
class Bookshelf(models.Model):
shelf_type = models.CharField(max_length=10, db_column='shelfType')
shelf_id = models.IntegerField(db_column='shelfId')
def __str__(self):
return self.shelf_type
class BookInfo(models.Model):
book_name = models.CharField(max_length=20, db_column='bookName')
book_time = models.DateTimeField(db_column='bookTime')
book_type = models.ForeignKey(Bookshelf, db_column='bookType', on_delete=models.CASCADE)
is_delete = models.BooleanField(db_column='isDelete')
# 元选项
class Meta:
db_table = 'bookinfo' # 表名; 默认: 应用名_表名
ordering = ['id'] # 排序(正序), 倒序:'-id', 随机:'?id'
def __str__(self):
return self.book_name
# 嵌套关联(自连接/自关联): 一张表存储所有地区(省市区)信息
class AreaInfo(models.Model):
area_title = models.CharField(max_length=20)
area_parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.area_title
数据样式:
id=1, title='浙江省', parent=null
id=2, title='杭州市', parent=1
id=3, title='上城区', parent=2
使用:
from booktest.models import AreaInfo
area = AreaInfo.objects.get(pk=220100) # 220100, 长春市, 220000(连云港市)
area.area_parent # 上级对象: <AreaInfo: 吉林省> (220000, 吉林省, null)
area.areainfo_set.all() # 下级对象: [<AreaInfo: 市辖区>, <AreaInfo: 南关区>(220102, 南关区, 220100), <AreaInfo: 宽城区> ...]
四、管理器Manager
- 管理器是模型类的属性, 用于对象与数据表之间的映射关系, 是我们用Django与数据库之间操作的接口, 一个模型可以有多个管理器(至少一个)
- 支持指定管理器(在模型中指定)
class BookInfo(models.Model):
# ...
# 指定管理器, 默认:objects
books = models.Manager()
- 自定义管理器(用于做一些额外的操作)(在模型中指定)
class BookInfoManager(models.Manager):
# 在创建时修改
def create(self, bookname):
b = BookInfo()
b.book_name = bookname
b.book_time = datetime.today()
b.book_type = Bookshelf.objects.get(pk=1)
b.is_delete = False
return b
# 修改查询结果
def get_queryset(self):
return super().get_queryset().filter(is_delete=False)
class BookInfo(models.Model):
# ...
# 一个模型可以使用多个管理器
# 指定管理器, 默认:objects
# 方式一: 使用指定管理器(同时多个自定义管理器也是可以的)
books = models.Manager()
# 方式二: 使用自定义管理器
books1 = BookInfoManager()
- 测试:python manage.py shell
from booktest.models import BookInfo
# 使用默认管理器(指定管理器之后, 默认管理器就不存在)
# Bookshelf.objects.all()
# 使用指定管理器
BookInfo.books.all()
# 使用自定义管理器
BookInfo.books1.all()
BookInfo.books1.create('456').save()
五、查询集
# --- 查询集 ---
'''
惰性执行: 创建查询集, 不会访问数据库, 调用数据时才会访问
查询集缓存: 查询过的结果集会进行缓存(不访问数据库), 所以查询集可重用(这点不同于Java)
--- 全部缓存 ---
例子: list = BookInfo.books1.all() # 不访问数据库
print([book.book_name for book in list]) # 访问数据库, 并缓存
print([book.book_name for book in list]) # 访问查询集缓存
--- 部分缓存 ---
例子: list = BookInfo.books1.all() # 不访问数据库
print([book.book_name for book in list[0:2]]) # 访问数据库, 并缓存
print([book.book_name for book in list[1:3]]) # 访问查询集缓存, 不在缓存去访问数据库, 不在缓存的那部分数据不缓存
过滤器:(支持链式调用)
--- 多个值 ---
all(): 查询所有
filter(is_delete=True): 通过满足
exclude(is_delete=True): 通过不满足
order_by(): 排序
values(): [{对象}, {对象}]
使用例子: BookInfo.books1.all()
--- 单个值 ---
get(pk=1): 单个满足条件的数据, 没找到DoesNotExist异常, 找到多个MultipleObjectsReturned异常
count(): 总条数
first():第一条数据
last(): 最后一条数据
exists(): 是否有数据, True:有
--- 下标限制(不支持-) ---
[0] / [1:3]
使用例子: BookInfo.books1.all()[1:3]
字段查询:
语法: 属性名__比较运算符=值(无需转义)
外键: 属性名_id
--- 比较运算符 ---
exact: ==, 区分大小写(不区分iexact)
contains: 是否包含, 区分大小写(不区分icontains)
startswith / endswith: 开头/结尾, 区分大小写(不区分istarswith / iendswith)
isnull / isnotnull: 是否为null
gt / gte / lt / lte: > / >= / < / <=
例子: BookInfo.books.filter(book_type_id__exact=1)
in: 是否在该[]范围内
例子: filter(pk__in=[1, 2, 3, 4, 5])
year / month / day / week_day / hour / minute / second / gt: 年 / 月 / 日 / 周 / 时 / 分 / 秒 /
例子: BookInfo.books.filter(book_time__year=1980)
例子: BookInfo.books.filter(book_time__gt=date(1980, 12, 31)) # >(1980,12,31), (date是datetime里的函数)
pk: 主键(primary key)
例子: BookInfo.books.filter(pk__lte=2)
--- 关联查询 ---
# 语法: 模型名__属性名__比较运算符
Bookshelf.objects.filter(bookinfo__book_name__in=[123, 456, 789]) # 查询书架上有"书名包含123,456,789"的所有书架
--- 聚合函数 ---
函数: Avg / Count / Max / Min / Sum
例子:
from django.db.models import Max
max_date = BookInfo.books.all().aggregate(Max('book_time')) # aggregate(Max(xxx))
F对象(用于字段与字段的比较)
语法:
字段名1__比较运算符=F('字段名2')
字段名=F('关联模型名__关联字段名')
例子:
from django.db.models import F
BookInfo.books.filter(id__exact=F('book_type_id')) # 对比同表字段
Bookshelf.objects.filter(id=F('bookinfo__id')) # 对比关联表字段
BookInfo.books.filter(book_time__lt=F('book_time') + timedelta(days=1)) # 直接运算
Q对象(or查询)
语法:
Q(字段__比较运算符=值)
取反: ~Q(字段__比较运算符=值)
与逻辑运算符一起使用: &(and) / |(or)
语法: Q(字段1__比较运算符1=值1) 逻辑运算符 Q(字段2__比较运算符2=值2)
例子:
from django.db.models import Q
list.filter(Q(pk__exact=1)) # id==1
list.filter(~Q(pk__exact=2)) # id=/=1
list.filter(Q(pk__exact=1) | Q(pk__exact=2)) # id=1or2
六、事务
from django.db import transaction
from django.shortcuts import redirect
# 事务
@transaction.atomic()
def order_handle(request):
# 事务回滚点, 操作失败可回到此点
tran_id = transaction.savepoint()
try:
# ...
# 提交事务
transaction.savepoint_commit(tran_id)
except Exception as e:
print(e)
# 回滚事务
transaction.savepoint_rollback(tran_id)
return redirect('xxx')
Python之Django的Model详解的更多相关文章
- Django之model详解
Django中的页面管理后台 Djano中自带admin后台管理模块,可以通过web页面去管理,有点想php-admin,使用步骤: 在项目中models.py 中创建数据库表 class useri ...
- Django入门基础详解
本次使用django版本2.1.2 安装django 安装最新版本 pip install django 安装指定版本 pip install django==1.10.1 查看本机django版本 ...
- 第五篇Django URL name 详解
Django URL name 详解 利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护. Djan ...
- Python安装、配置图文详解(转载)
Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境(I ...
- 【和我一起学python吧】Python安装、配置图文详解
Python安装.配置图文详解 目录: 一. Python简介 二. 安装python 1. 在windows下安装 2. 在Linux下安装 三. 在windows下配置python集成开发环境( ...
- Python中的高级数据结构详解
这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...
- [转]使用python来操作redis用法详解
转自:使用python来操作redis用法详解 class CommRedisBase(): def __init__(self): REDIS_CONF = {} connection_pool = ...
- Python中格式化format()方法详解
Python中格式化format()方法详解 Python中格式化输出字符串使用format()函数, 字符串即类, 可以使用方法; Python是完全面向对象的语言, 任何东西都是对象; 字符串的参 ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
随机推荐
- 初识android界面布局
1.活动 活动是android开发中最基本的概念,也是最容易吸引用户的地方,是一种可以包含用户界面的组件. Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节.具体如下: (1)o ...
- 【原创】由于python的导入方式引起的深坑
目录结构: test/ sacc/ __init__.py app.py logger.py /views __init__.py main.py 事情是这样的,logger里面是一个类LoggerF ...
- Java基础知识强化之集合框架笔记79:HashMap的实现原理
1. HashMap的实现原理之 HashMap数据结构: HashMap是对数据结构中哈希表(Hash Table)的实现, Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Val ...
- Python基础.md
数据结构 列表 访问 list1 = ['java','C','C++','Python'] In [10]: list1[1] Out[10]: 'C' In [11]: list1[-1] Out ...
- Java基础加强之反射
1.什么是反射? 反射其实就是动态的加载类,我们在写JDBC的时候加载驱动Class.forName("xxx")时就涉及到了反射. 反射机制是在运行状态中,对于任意一个类,都能够 ...
- KMP算法用JavaScript实现
KMP算法是字符串匹配的经典算法,简称 看毛片, 理论知识请直接看阮一峰老师的这篇文章,我看完文章之后尝试对算法进行了实现. 一句话总结KMP算法的核心思想:就是跳过已经对比的部分 而KMP算法的核心 ...
- Docker实战(十)之分布式处理与大数据平台
分布式系统和大数据处理平台是目前业界关注的热门技术. 1.RabbitMQ RabbitMQ是一个支持AMQP的开源消息队列实现,由Erlang编写,因以高性能.高可用以及可伸缩性出名.它支持多种客户 ...
- Docker实战(六)之使用Dockerfile创建镜像
Dockervile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义镜像. 1.基本结构 Dockerfile由一行行命令语句组成,并且支持以#开头的注释行. 一般而言,Do ...
- 专家PID控制
1.专家PID控制原理 PID专家控制的实质是,基于受控对象和控制规律的各种知识,无需知道被控对象的精确模型,利用专家经验来设计PID参数.专家PID控制是一种直接型专家控制器. 典型的二阶系统单位阶 ...
- P1481 魔族密码
题目描述 风之子刚走进他的考场,就…… 花花:当当当当~~偶是魅力女皇——花花!!^^(华丽出场,礼炮,鲜花) 风之子:我呕……(杀死人的眼神)快说题目!否则……-_-### 花花:……咦好冷我们现在 ...