[Django笔记] models 深入学习
对着官方文档撸一遍,顺便做点笔记
models 定义了本应用的数据库表结构。底层可以由不同的数据库封装实现,因为不同的数据库字段类型不一样,因此,跟以往直接用单一数据库(如mysql)建立的应用有很大的区别。
models里面定义的数据类型基本上都是基础类型,在mysql用的比较多的 timestamp 貌似需要自己去做扩展:
class MyDateField(models.Field):
def db_type(self, connection):
if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
return 'datetime'
else:
return 'timestamp'
DatetimeField
auto_now_add = True; 设置添加时默认当前时间。这里并不是通过数据库来实现,而是django在添加的时候去计算时间。因此涉及到时区问题:
settings.py 设置 USE_TZ = True 后,django会使用UTC标准时间存入数据库。这个时候取出的 datetimefield 需要转换时区才能正确显示。
因此一般情况下,如果应用不用考虑跨时区问题,设置 USE_TZ = False 一劳永逸
查询出来的 datetimeField 是一个 <'datetime' object>,根据自己需要进行格式化输出
ForeignKeyField
外键关联,如果关联的外键表已经定义(在前面),直接用class名;若还未定义(在后面),用类名字串。
class Spider(models.Model):
"""
爬虫信息配置
"""
name = models.CharField('爬虫名称', max_length=50, default='', db_index=True)
c_name = models.CharField('爬虫名称', max_length=50, default='')
domain = models.CharField('爬虫域名', max_length=150, default='')
n_start = models.IntegerField('起始页数', default=0)
n_end = models.IntegerField('终止页数', default=0)
content_type = models.ForeignKey(
'ContentType',
related_name='spider_content_type',
on_delete=models.CASCADE,
)
def __str__(self):
return '%s[%s]' % (self.c_name, self.name)
class ContentType(models.Model):
"""
抓取内容类型
"""
ACTIVE = (
(0, 'active'),
(1, 'discard'),
)
name = models.CharField('内容类型', max_length=50, default='')
max_item = models.IntegerField('每个爬虫最大抓取数', default=10)
expire_time = models.IntegerField('过期时间(天)', default=30)
active = models.BooleanField('是否废弃', choices=ACTIVE, db_index=True, default=0)
def __str__(self):
return self.name
related_name 代表在外键索引表中使用的查询引用。
举个例子,A是主表,B表关联A_id,related_name为 related_a_id
仅当在A中查询 b_id 时,使用 A.objects.filter(related_a_id=b_id)。
下面是更详细的举例
>>>
>>> Spider.objects.all()
<QuerySet [<Spider: 知乎[zhihu1]>, <Spider: 贴吧[tieba1]>, <Spider: LOL电影天堂[ddtt]>]>
>>>
>>> Spider.objects.get(id=1)
<Spider: 知乎[zhihu1]>
>>> Spider.objects.get(id=1).content_type
<ContentType: 图片>
>>>
>>> Spider.objects.filter(content_type=1)
<QuerySet [<Spider: 知乎[zhihu1]>, <Spider: 贴吧[tieba1]>]>
>>>
>>> ContentType.objects.filter(active=0)
<QuerySet [<ContentType: 图片>, <ContentType: 电影资源>, <ContentType: 影评>, <ContentType: 小说>]>
>>> ContentType.objects.filter(spider_content_type=1)
<QuerySet [<ContentType: 图片>]>
>>> ContentType.objects.filter(spider_content_type=2)
<QuerySet [<ContentType: 图片>]>
>>> ContentType.objects.filter(spider_content_type__in=[1,2,3])
<QuerySet [<ContentType: 图片>, <ContentType: 图片>, <ContentType: 电影资源>]>
>>>
ForeignKey 默认会联接主键,如果是关联主键,需要手动指定to_field=relate_field。并且,实际创建的字段名会自动加上 _id 后缀
choice
类似于枚举类型,应该是为了在admin中更加方便管理。但是在业务使用的时候个人觉得很麻烦:
XxxModel.SomeChoice[0][0]
Meta.db_table
Django的models 类名必须为驼峰,然后会自动全部转成小写并且在前面加上app前缀。如果想使用下划线分割单词,需要手动指定表明
class Meta:
verbose_name = 'cat imgs'
verbose_name_plural = 'cat imgs'
db_table = 'cat_imgs'
ManyToManyField
如果两个表有n:n的对应关系,只需要在一个表里声明。这时候Django会自动建立关联表。
但是通常关联表还会包含其他字段信息,这时候需要通过 throgh 来指定一个关系表,并且显式地声明这个表的结构
# relationship with comment
comments = models.ManyToManyField(
User,
through='PicComments',
through_fields=('img', 'author'),\
)
objects
在使用models查询的时候会先调用一个objects对象。
这个对象我们可以通过继承扩展封装一些自定义方法,或者对queryset进行底层的过滤封装。
class ImgManager(models.Manager):
'''
custom img model manager
'''
def get_queryset(self):
return super(ImgManager, self).get_queryset().filter(img_status=0)
def with_info(self, offset=0, limit=30):
from django.db import connection
result_list = []
with connection.cursor() as cursor:
cursor.execute('''
SELECT i.id,i.img_src,i.img_from,i.img_desc,IFNULL(l.likes,0)likes,
IFNULL(s.comments,0)comments,IFNULL(s.stars,0)stars FROM cat_imgs i
LEFT JOIN
(SELECT img_id,COUNT(DISTINCT user_id) likes FROM cats_pic_likes WHERE is_like=1 GROUP BY img_id ) l
ON i.id=l.img_id
LEFT JOIN
(SELECT img_id,comments,stars FROM cats_pic_stars) s
ON i.id=s.img_id
WHERE img_status=0 LIMIT %d,%d
''' % (offset, limit))
for row in cursor.fetchall():
p = self.model(id=row[0], img_src=row[1], img_from=row[2], img_desc=row[3])
p.n_likes = row[4]
p.n_comments = row[5]
p.n_stars = row[6]
p.n_star = 0 if row[5]==0 else row[6]//row[5]
result_list.append(p)
return result_list
queryset API
values()字典形式的数据values_list()列表形式的数据raw()原始sql- 其他复杂的都可以在官网查询
[Django笔记] models 深入学习的更多相关文章
- [Django笔记] admin 深入学习
admin django 内置的管理后台,大部分时候可以通过对admin进行配置来提高开发效率. 数据列表展示 默认情况下显示一个models-objects的列表,如果model定义了 __str_ ...
- Django笔记&教程 4-2 模型(models)中的Field(字段)
Django 自学笔记兼学习教程第4章第2节--模型(models)中的Field(字段) 点击查看教程总目录 参考:https://docs.djangoproject.com/en/2.2/ref ...
- Django笔记&教程 4-3 模型(models)主键外键
Django 自学笔记兼学习教程第4章第3节--模型(models)主键外键 点击查看教程总目录 参考:https://docs.djangoproject.com/en/2.2/ref/models ...
- Django模型层ORM学习笔记
一. 铺垫 1. 连接Django自带数据库sqlite3 之前提到过Django自带一个叫做sqlite3的小型数据库,当我们做本地测试时,可以直接在sqlite3上测试.不过该数据库是小型的,在有 ...
- 【Django笔记2】-创建应用(app)与模型(models)
1,创建应用(app) 一个完善的网站需要许多功能提供不同的服务.如果所有的功能都在一个文件中,不利于项目多人共同开发,以及后续的维护.此时可以针对一个要实现的功能,创建一个app,将多个app结 ...
- django笔记-模型数据模板呈现过程记录(多对多关系)
首先,推荐一个网址:http://www.tuicool.com/articles/BfqYz2F,因为这里的比我的要有条理,更有利于各位的理解. 以下仅为为个人一次不完整的笔记: 环境:ubuntu ...
- Django笔记 —— Admin(Django站点管理界面)
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...
- Django笔记 —— 模型
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...
- Django笔记&教程 5-2 进阶查询——Queryset
Django 自学笔记兼学习教程第5章第2节--进阶查询--Queryset 点击查看教程总目录 Queryset相关内容其实蛮多的,本文只介绍一些常用的,详细的推荐查询官方文档:queryset-a ...
随机推荐
- window.onload 添加多个函数绑定
window.onload = function(){alert(2)} function addEvent (fun) { var old = window.onload; if(typeof ol ...
- jenkins-小知识点
如果想停止jenkins运行 控制面板-服务-查看本地服务-选中jenkins 1.启动类型改为手动 2.改为禁止 使用的时候,每次都改一下状态
- Chrome_01_点击 Google搜索结果在新的页面打开
方法一:Ctrl + 左键 Chrome浏览器中,通过 Ctrl + 左键 ,是在新标签中打开的,通过 Shift + 左键 ,是在新窗口中打开的. 方法二: 1.登录 Google 2.进入下面的设 ...
- json 文件解析与应用
第一步:首先弄一个 json 文件 我这里成为 config.json 内容如下 { ": { , "desc":"中华人民共和国" }, &qu ...
- 动作基类 CCAction
CCAction动作基类关系 class CC_DLL CCAction : public CCObject { public: CCAction(void); virtual ~CCAction(v ...
- 【二叉树的递归】06填充每个节点中的下一个正确的指针【Populating Next Right Pointers in Each Node】
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树 struct Tr ...
- SPOJ Query on a tree II (树剖||倍增LCA)(占位)
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, ...
- LOJ2305 「NOI2017」游戏
「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...
- iOS重写drawRect方法实现带箭头的View
创建一个UIView的子类,重写drawRect方法可以实现不规则形状的View,这里提供一个带箭头View的实现代码: ArrowView.h #import <UIKit/UIKit.h&g ...
- XML的二十个热点问题
这些日子,几乎每个人都在谈论XML (Extensible Markup Language),但是很少有人真正理解其含义.XML的推崇者认为它能够解决所有HTML不能解决的问题,让数据在不同的操作系统 ...