对着官方文档撸一遍,顺便做点笔记

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 深入学习的更多相关文章

  1. [Django笔记] admin 深入学习

    admin django 内置的管理后台,大部分时候可以通过对admin进行配置来提高开发效率. 数据列表展示 默认情况下显示一个models-objects的列表,如果model定义了 __str_ ...

  2. Django笔记&教程 4-2 模型(models)中的Field(字段)

    Django 自学笔记兼学习教程第4章第2节--模型(models)中的Field(字段) 点击查看教程总目录 参考:https://docs.djangoproject.com/en/2.2/ref ...

  3. Django笔记&教程 4-3 模型(models)主键外键

    Django 自学笔记兼学习教程第4章第3节--模型(models)主键外键 点击查看教程总目录 参考:https://docs.djangoproject.com/en/2.2/ref/models ...

  4. Django模型层ORM学习笔记

    一. 铺垫 1. 连接Django自带数据库sqlite3 之前提到过Django自带一个叫做sqlite3的小型数据库,当我们做本地测试时,可以直接在sqlite3上测试.不过该数据库是小型的,在有 ...

  5. 【Django笔记2】-创建应用(app)与模型(models)

    1,创建应用(app) ​ 一个完善的网站需要许多功能提供不同的服务.如果所有的功能都在一个文件中,不利于项目多人共同开发,以及后续的维护.此时可以针对一个要实现的功能,创建一个app,将多个app结 ...

  6. django笔记-模型数据模板呈现过程记录(多对多关系)

    首先,推荐一个网址:http://www.tuicool.com/articles/BfqYz2F,因为这里的比我的要有条理,更有利于各位的理解. 以下仅为为个人一次不完整的笔记: 环境:ubuntu ...

  7. Django笔记 —— Admin(Django站点管理界面)

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  8. Django笔记 —— 模型

    最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...

  9. Django笔记&教程 5-2 进阶查询——Queryset

    Django 自学笔记兼学习教程第5章第2节--进阶查询--Queryset 点击查看教程总目录 Queryset相关内容其实蛮多的,本文只介绍一些常用的,详细的推荐查询官方文档:queryset-a ...

随机推荐

  1. 分享知识-快乐自己:idea的断点调试

    1:Step Over ,进入下一步,如果是方法,那就直接跳过(F8) 2:Step Into,进入下一步,如果是方法,就进入方法内部,但是不会进入jdk封装的方法.(F7) 3:Force Step ...

  2. 理解WCF(第二部分,部分參考他人)

    該篇的主題:wcf到底是怎工作的? 一.什么是分布式: 首先看一张图: 由上图对比我们可以发现,区别就是前者把服务器放在了一台电脑上,而后者把服务器放在了多台电脑上.这样多台电脑处理起来的速度比一台电 ...

  3. Redis安装以及基本操作命令

    Redis安装 cd redis-2.6.14make PREFIX=/usr/local/redis install 可能会出现的错误提示>>提示1:make[3]: gcc:命令未找到 ...

  4. Java_异常_06_ Unsupported major.minor version 52.0

    二.参考资料 1.如何解决Unsupported major.minor version 52.0问题? 2.Unsupported major.minor version 52.0 3. Unsup ...

  5. BEC listen and translation exercise 43

    Reach for the stars so if you fall you land on a cloud.飞向星空吧,就算坠落,接住你的也是云彩. Anyway, exam failure can ...

  6. Java IO 简记

    1.File 类: l  java.io.File类:文件和目录路径名的抽象表示形式,与平台无关 l  File 能新建.删除.重命名文件和目录,但 File 不能访问文件内容本身.如果需要访问文件内 ...

  7. ACM学习历程—HDU5476 Explore Track of Point(平面几何)(2015上海网赛09题)

    Problem Description In Geometry, the problem of track is very interesting. Because in some cases, th ...

  8. UNITY_MATRIX_IT_MV[Matrix]

    http://blog.csdn.net/cubesky/article/details/38682975 前面发了一篇关于unity Matrix的文章. http://blog.csdn.NET/ ...

  9. Oracle 12c 多租户在 CDB 中 Plug A PDB,Unplugging A PDB

    Oracle 数据库 12 c 中介绍了多租户选项允许单个容器数据库 (CDB) 来承载多个单独的可插拔数据库 (PDB).本文简单的演示了如何在 CDB 中 Plug A PDB,Unpluggin ...

  10. javascript面向对象的测试实例