Django ORM基本应用与原理剖析

简介: 1.ORM构建数据表由于每一个数据表对应一个Model定义,每一个Model都是一个Python类,所以,Model之间是可以继承的。Django规定,所有的Model都必须继承自django.db.models.Model


1.ORM构建数据表


由于每一个数据表对应一个Model定义,每一个Model都是一个Python类,所以,Model之间是可以继承的。Django规定,所有的Model都必须继承自django.db.models.Model


Model中的所有字段都是django.db.models.Field的子类,Django会根据Field的类型确定数据库表的字段类型


首先定义定义抽象Model基类:


class BaseModel(models.Model):
    class Meta:
        # 抽象类,表现为BaseModel不会创建数据表
        abstract = True
        # 按照创建时间逆序排序
        ordering = ['-created_time']
    # 定义了两个类属性:created_time和last_modified,且都是DateTimeField类型
    # auto_now_add用于将首次创建对象时间设置为当前时间
    # auto_now用于将每次保存对象时间设置为当前时间
    created_time = models.DateTimeField(auto_now_add=True, help_text=u'创建时间')
    last_modified = models.DateTimeField(auto_now=True, help_text=u'修改时间')
    # 优化打印(print)Model实例的样式
    def __str__(self):
        raise NotImplementedError


由于BaseModel直接继承自django.db.models.Model,所以,我们创建的实体数据表可以继承自Base Model,从而实现间接继承

例如:话题表


class Topic(BaseModel):
    title = models.CharField(max_length=255, unique=True, help_text=u'话题标题')
    content = models.TextField(help_text=u'话题内容')
    is_online = models.BooleanField(default=True, help_text=u'话题是否在线')
    user = models.ForeignKey(to=User, to_field='id', on_delete=models.CASCADE, help_text=u'关联用户表')
    def __str__(self):
        return '%d:%s' % (self.id, self.title[0:20]


Topic中除了基本类型的字段定义之外,还包含了一个外键(ForeignKey)引用的user字段

评论表:


class Comment(BaseModel):
    content = models.CharField(max_length=255, help_text=u'话题评论')
    topic = models.ForeignKey(to=Topic, to_field='id', on_delete=models.CASCADE, help_text=u'关联话题表')
    up = models.IntegerField(default=0, help_text=u'支持')
    down = models.IntegerField(default=0, help_text=u'反对')
    def __str__(self):
        return '%d:%s' % (self.id, self.content[0:20])


2.数据迁移


首先,在settings.py文件中添加此Model视图的app:(post.apps.PostConfig)


INSTALLED_APPS = [
    'post.apps.PostConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]


生成迁移文件:


python manage.py makemigrations post


执行migrate命令将Models映射为数据库的表:


python manage.py migrate


生成的表结构:


3.Model相关的概念与使用方法


Model的组成部分


每个Model都是一个Python类,且通常会包含四个部分:继承自django.db.models.Model、Model元数据声明(Meta内部类)、若干个Field类型的字段以及__str__方法


Meta元数据类属性说明


Meta类用于定义Model的元数据,即不属于Model的字段,但是可以用来标识它的一些属性


abstract:


一个布尔类型的变量,如果设置为True,则标识当前的Model是抽象基类,这个元选项不具有传递性,只对当前声明的类有效。例如,对于之前定义的BaseModel,用abstract声明为抽象基类,但是子类Topic和Comment不受影响


db_table:


这个字段用于指定数据表的名称


默认会使用Django的表名生成规则,例如Topic会映射到post_topic表。如果想让Topic映射到topic表,定义db_table='topic'即可


ordering:


用于指定获取对象列表时的排序规则

按照created_time逆序排序,可以定义:


ordering = ['-created_time']


先按照created_time逆序排序,再按照last_modified正序排序:


ordering = ['-created_time', 'last_modified']


indexes:


它是一个列表类型的元选项,用来定义Model的索引



fields:一个列表对象,用于指定索引的字段,是必填项,且至少包含一个字段。

name:用于标识索引的名称,是可选的,如果不提供,Django会根据不同的数据库生成合适的索引名。

db_tablespace:表空间,也是可选的,常见于PostgreSQL、Oracle数据库,用于优化数据库性能

unique_together:


标识联合唯一约束,在数据库层面表现为联合唯一索引



Field的通用字段选项


blank:


对于任何一个属性,默认是不允许输入空值的,如果允许这种情况发生,需要设置blank=True


unique:


如果一个字段设置了unique=True,则表示唯一性索引


null:


规定这个字段的数据是否可以是空值


db_index:


如果该字段经常作为查询的条件,那么就需要考虑设置db_index选项,以加快数据的检索速度


default:


用于给字段设置默认值


choices:


设置了choices的字段在管理后台的显示上会由文本框变成选择框,选择框中的可选值就是choices中的元组



help_text:


这个选项用于在表单中显示字段的提示信息。例如在管理后台的编辑页面,对应在字段输入框的下方会显示该选项设定的值


基础字段类型


IntegerField:整型字段

Django还提供了SmallIntegerField(小整数)、BigIntegerField(64位整数)和PositiveIntegerField(只允许存储大于等于0的整数)等字段类型用来满足存储整数的不同业务场景

AutoField:一个根据ID自增的IntegerField

如果觉得AutoField的取值范围不够用,可以考虑使用BigAutoField

CharField:字符字段

TextField:也是用于存储字符类型的字段,但是它用于存储大文本

BooleanField:布尔类型

DateField和DateTimeField:标识时间的

它们都有两个特殊的参数选项可以设置

①auto_now:这个选项应用在对象保存的时候,会自动设置为当前时间

②auto_now_add:当首次创建对象的时候,会自动将字段设置为当前时间

EmailField:专门用来存储电子邮件地址的

除了之前介绍的几种常见的类型之外,还有GenericIPAddressField用于存储IP地址、URLField用于存储URL、FloatField用于存储浮点数的字段类型等


关系字段类型


多对一


实例:


user = models.ForeignKey(to=User, to_field='id', on_delete=models.CASCADE, help_text=u'关联用户表')


to:指定所关联的Model


on_delete:当删除关联表的数据时,Django将根据这个参数设定的值确定应该执行什么样的SQL约束


CASCADE:级联删除,它是大部分ForeignKey的定义应该选择的约束。它的表现是删除了“一”,则“多”会被自动删除

PROTECT:删除被引用对象时,将会抛出ProtectedError异常

SET_NULL:设置删除对象所关联的外键字段为null。以Topic和Comment的关系举例:删除了Topic,与之相关联的Comment的topic字段会被设置为null

SET_DEFAULT:将外键字段设置为默认值

SET(value):删除被引用对象时,设置外键字段为value

DO_NOTHING:不做任何处理


一对一


实例:


user = models.OneToOneField(to=User, on_delete=models.CASCADE, parent_link=False,
                             help_text=u'关联用户表')


多对多关系类型


实例:


books = models.ManyToManyField(to=Book)
目录
相关文章
|
9月前
|
缓存 监控 中间件
Django中间件自定义开发指南:从原理到实战的深度解析
Django中间件是Web应用的“交通警察”,在请求与响应过程中进行全局处理,适用于身份验证、日志记录、性能监控等功能。本文详解中间件的工作原理、开发步骤及实战案例,帮助开发者掌握自定义中间件的构建方法,提升Django应用的可维护性与扩展性。
503 0
|
SQL 安全 数据库
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
1012 173
|
前端开发 JavaScript UED
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
通过在Django项目中集成Channels和WebSocket,我们能够为前后端分离的应用添加实时通信功能,实现诸如在线聊天、实时数据更新等交互式场景。这不仅增强了应用的功能性,也提升了用户体验。随着实时Web应用的日益普及,掌握Django Channels和WebSocket的集成将为开发者开启新的可能性,推动Web应用的发展迈向更高层次的实时性和交互性。
415 1
|
IDE 关系型数据库 MySQL
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
这篇文章是关于如何创建一个Django框架,介绍Django的项目结构和开发逻辑,并指导如何创建应用和编写“Hello, World!”程序的教程。
890 3
Django学习一:创建Django框架,介绍Django的项目结构和开发逻辑。创建应用,编写主包和应用中的helloworld
|
SQL 定位技术 数据库
深入探索Django ORM:高效数据库操作的秘诀####
本文旨在为读者揭开Django ORM(对象关系映射)的神秘面纱,通过一系列生动的比喻和详实的案例,深入浅出地讲解其核心概念、工作原理及高级特性。我们将一起探讨如何利用Django ORM简化数据库交互,提升开发效率,同时确保数据的一致性和安全性。不同于传统的技术文档,本文将以故事化的形式,带领读者在轻松愉快的氛围中掌握Django ORM的精髓。 ####
|
SQL 监控 数据库
深入探索Django ORM:高效数据操作的秘诀与实践####
在当今的Web开发领域,提升数据访问层的效率是优化应用性能的关键。本文旨在通过剖析Django框架中的ORM(对象关系映射)机制,揭示其如何简化数据库交互,并探讨一系列高级技巧与策略,帮助开发者构建更高效、可维护的数据访问代码。我们不涉及安装步骤或基础概念,而是聚焦于实战经验分享,旨在为中高级开发者提供深度洞见。 ####
|
中间件 应用服务中间件 nginx
Nginx+uWSGI+Django原理
Nginx+uWSGI+Django原理
|
数据管理 数据挖掘 调度
Django后端架构开发:URLconf到ORM深度剖析
Django后端架构开发:URLconf到ORM深度剖析
220 1