Model 相关操作
反向外键
class DictKanaItem(models.Model):
# ....
class DictKanjiItem(models.Model):
kana = models.ForeignKey('DictKanaItem', related_name='kanji', on_delete=models.PROTECT)
# Onetoone 同理
update_date = models.DateField('更新时间', auto_now=True)
create_time = models.DateTimeField('创建时间', auto_now_add=True, null=True)
可以使用 DictKanaItem.kanji
(列表) 和 DictKanjiItem.kana
双向查询
F 运算
用于动态运算
record_item = RecordItem.object.filter(sex=1).first() # 一个 QuerySet
record_item.score = F('score') + 1 # score = score + 1
record_item.save() # 每运行一次 save 都会 +1
数据库的 Bitwise 操作
获取 number
字段第一位为 1 的所有行(相当于所有奇数)
result = Item.objects.extra(where=['number & 1 = 1'])
# 相当于数据库的 where number & 1 = 1
事物锁
处理并发情况保持数据一致性可以使用乐观锁或者悲观锁
悲观锁
锁住某个资源, 不让其他人使用(排他), 直到完成工作后释放
# 外面需要 @transaction.atomic 或者 with transaction.atomic():
# 使用 select_for_update 可以确保该资源可以被唯一的占用直到事物结束
item = RecordItem.objects.select_for_update().get(id=1)
# some operation
item.save()
乐观锁
正常运行, 如果发现失败就进行回滚
with transaction.atomic():
# some operation
for i in range(1,5):
# 直接修改, 如果成功的行数为 1 表示修改成功
updated = RecordItem.objects.filter(id=1).update(key=value)
if updated > 0:
return 'OK'
# 连续多次修改失败
transaction.rollback()
return 'Failed'
批量操作
使用批量操作的方式可以简化 SQL 操作以提升速度
RecordItem.objects.filter(sex=1).update(sex=0) # 批量修改
RecordItem.objects.filter(sex=1).delete() # 批量删除
# 多个不同对象 save 用 bulk_update
record_item[0].sex=0
# record_item.save() # Bad
record_item[1].sex=1
# record_item.save() # Bad
RecordItem.objects.bulk_update(record_item, ['sex']) # Better
# Manytomany 字段操作
# ManyToMany 的和添加或删除使用一个 .add() 或 .remove()
my_band.members.add(me, my_friend)
# my_band.members.remove(me) # Bad
# my_band.members.remove(my_friend) # Bad
my_band.members.remove(me, my_friend) # Better
# bulk_create
RecordItem.objects.bulk_create([ # 批量新建
RecordItem(sex=1)
RecordItem(sex=1)
])
字段为 DateTimeField,通过日期查询
__date
可以将 DateTime 转为 Date
import datetime
date = datetime.datetime.strptime('2019-09-09', '%Y-%m-%d').date()
result = Item.objects.filter(time__date=date)
数据库相关
查看 database 占用的磁盘空间
select TABLE_NAME, concat(truncate(data_length/1024/1024,2),' MB') as data_size,
concat(truncate(index_length/1024/1024,2),' MB') as index_size
from information_schema.tables where TABLE_SCHEMA = 'database_name'
order by data_length desc;