type python django models_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, False

CharField(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 # 上级对象: (220000, 吉林省, null)

area.areainfo_set.all() # 下级对象: [, (220102, 南关区, 220100), ...]

四、管理器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')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值