Django 自定义表名和字段名
Django 自定义表名和字段名
通过db_table和db_column自定义数据表名和字段名
假如你的数据库里已经有了一张数据表,且该表包含多个字段,你希望通过Django直接访问该数据表的各个字段而不是重新建立新表,你这时可以通过db_table指定数据表名,还可以通过db_column指定希望访问的字段名。
在我们创建一个模型时,Django的ORM会根据应用名(app name), 模型名(model name)和字段名(field name)自动在数据库中创建数据表。比如我们有一个Blog的应用,里面有Article模型, 其中Article模型有title这个字段,那么Django默认会创建一个名为blog_article的数据表,其中有title这个字段。假如我们希望把表名改为article,标题改为article_title,以便与已经存在的数据表或字段建立映射关系,我们可以按如下代码操作。

class Article(models.Model):
"""文章模型"""
# 通过db_column自定义数据表中字段名
title = models.CharField('标题', max_length=200, db_column='article_title')
slug = models.SlugField('slug', max_length=60, blank=True)
def __str__(self):
return self.title
class Meta:
db_table = 'article' # 通过db_table自定义数据表名

通过db_index和Meta index选项给数据表字段建立索引
使用索引可快速访问数据库表中的特定信息。数据库索引好比是一本书前面的目录,没有索引目录的话,你访问书中某个页面需要从第1页遍历到最后一页,如果有目录,你可以快速地根据目录查找到所需要的页面。Django项目中如果你需要频繁地对数据表中的某些字段(如title)使用filter(), exclude()和order_by()方法进行查询,我们强烈建议你对这些字段建议索引(index), 提升查询效率。
要对模型中的某个字段建立数据库索引,你可以使用db_index选项,也可以使用Meta选项建立索引。使用Meta选项的好处是你可以一次性对多个字段建立索引,还可以对多个字段建立组合索引。

方法一: 使用db_index选项 class Article(models.Model):
"""文章模型""" # 使用db_index=True对title建立索引
title = models.CharField('标题', max_length=200, db_index=True)


方法二: 使用Meta选项 class Article(models.Model):
"""文章模型"""
title = models.CharField('标题', max_length=200,) class Meta:
indexes = [
models.Index(fields=['title']),
]

Django主从数据库配置
当你刚刚开始建立一个网站时,可能每天只有数十到上百人访问。这时你只有一个数据库,所有APP的数据表也都放一起的,一台普通的服务器能够应付, 也便于维护。但是当访问量上来后,你会发现一台服务器和一个数据库会根本应付不了这个压力。这时你可能希望实现数据库的主从配置,读写分离,把各个数据库放在不同的服务器上,有的专门负责写入,有的专门负责读取,这时你就要学会使用Django同时连接多个数据库,并自定义读写操作。
第一步 修改项目的 settings 配置
在 settings.py 中配置需要连接的多个数据库名称和登录信息。在下例中我们自定义了3个数据库,1个主数据库(primary), 2个从数据库(replica)。

#project/settings.py
DATABASES = {
'default': {},
'primary': {
'NAME': 'primary',
'ENGINE': 'django.db.backends.mysql',
'HOST': 'xxxx',
'PORT': 'xxxx',
'USER': 'mysql_user',
'PASSWORD': 'spam',
},
'replica1': {
'NAME': 'replica1',
'ENGINE': 'django.db.backends.mysql',
'HOST': 'xxxx',
'PORT': 'xxxx',
'USER': 'mysql_user',
'PASSWORD': 'eggs',
},
'replica2': {
'NAME': 'replica2',
'ENGINE': 'django.db.backends.mysql',
'HOST': 'xxxx',
'PORT': 'xxxx',
'USER': 'mysql_user',
'PASSWORD': 'bacon',
},
}

我们还需要在 settings.py 添加我们手动编写的数据库路由Router。路由的作用是为数据库的读写制定规则。
DATABASE_ROUTERS = ['Project.database_router.PrimaryReplicaRouter']
注意: 主从数据库的同步是通过MySQL配置实现的,而不是Django实现的。Django只负责多个数据库的访问,不负责各个数据库的同步工作。如果你定义了多个路由,请一定注意路由的执行顺序。
第二步 自定义数据库路由Router
在Django项目的根目录下创建 database_router.py 文件, 添加如下代码,自定义数据库路由。该路由规定了读取数据时将随机从replica1和replica2数据库中读取,而写入数据总是写入主数据库primary。该路由还允许三个数据库中的字段建立联系。

class PrimaryReplicaRouter(object):
def db_for_read(self, model, **hints):
"""
Reads go to a randomly-chosen replica.
"""
return random.choice(['replica1', 'replica2']) def db_for_write(self, model, **hints):
"""
Writes always go to primary.
"""
return 'primary' def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the primary/replica pool.
"""
db_list = ('primary', 'replica1', 'replica2')
if obj1._state.db in db_list and obj2._state.db in db_list:
return True
return None def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
All models end up in this pool.
"""
return True

一个数据库路由是一个类,这个类最多有四个方法:
db_for_read(model, **hints)
建议 model 对象进行读操作时使用的数据库。如果一个数据库操作可以提供对选择数据库有用的附加信息,那么可以通过 hints 字典提供。如果没有建议则返回 None 。
db_for_write(model, **hints)
建议 model 对象进行写操作时使用的数据库。如果一个数据库操作可以提供对选择数据库有用的附加信息,那么可以通过 hints 字典提供。如果没有建议则返回 None 。
allow_relation(obj1, obj2, **hints)
当 obj1 和 obj2 之间允许有关系时返回 True ,不允许时返回 False ,或者没有意见时返回 None 。这是一个纯粹的验证操作,用于外键和多对多操作中,两个对象的关系是否被允许。
allow_migrate(db, app_label, model_name)
决定 model 是否可以和 db 为别名的数据库同步。如果可以返回True , 如果不可以返回 False ,或者没有意见时返回 None 。
Django项目按APP分库
在大型web项目中,我们常常会创建多个app来处理不同的业务,如果希望实现app之间的数据库分离,比如app01走数据库db1,app02走数据库db2,而不是实现读写分离。我们可以定义如下所示的数据库路由, 然后将其加入settings.py 。

class AppDBRouter:
def db_for_read(self, model, **hints):
if model._meta.app_label == 'app01':
return 'db1'
if model._meta.app_label == 'app02':
return 'db2' def db_for_write(self, model, **hints):
if model._meta.app_label == 'app01':
return 'db1'
if model._meta.app_label == 'app02':
return 'db2'

由于manage.py一次只能创建一个数据库,我们可以使用--database选项来依次创建我们需要的数据库。例如:
将app01下models中的表创建到db01的数据库”db1”中
python manage.py migrate --database=db1
将app02下models中的表创建到db02的数据库”db2”中
python manage.py migrate --database=db2
在使用多数据库时,我们可以使用using方法来手动选择需要读写的数据库,如下所示:
Aricle.objects.using('db1').all()
article_object.save(using='db2')
Django中使用多数据库注意事项:
django 目前不为跨多个数据库的外键关系(ForeinKey)或多对多关系提供任何支持。模型定义的任何外键和多对多关系字段都必须存在一个数据库内。
Django 自定义表名和字段名的更多相关文章
- 尚硅谷面试第一季-11MyBatis中当实体类中的属性名和表中的字段名不一样怎么办
问题: MyBatis中当实体类中的属性名和表中的字段名不一样 ,怎么办 ? 解决方案: 1.写sql语句时起别名 <!-- id属性:必须是接口中方法的方法名 resultType属性:必须是 ...
- SQL Server 2008 R2——根据数据查找表名和字段名 根据脏数据定位表和字段
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- mybatis动态调用表名和字段名
以后慢慢启用个人博客:http://www.yuanrengu.com/index.php/mybatis1021.html 一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用 ...
- SQL 查询所有表名、字段名、类型、长度、存储过程、视图
-- 获得存储过程创建语句 select o.xtype,o.name,cm.text from syscomments cm inner join sysobjects o on o.id=cm.i ...
- sqlserver查询所有表名、字段名、类型、长度和存储过程、视图的创建语句
-- 获得存储过程创建语句 select o.xtype,o.name,cm.text from syscomments cm inner join sysobjects o on o.id=cm.i ...
- Oracle 查询库中所有表名、字段名、字段名说明,查询表的数据条数、表名、中文表名、
查询所有表名:select t.table_name from user_tables t;查询所有字段名:select t.column_name from user_col_comments t; ...
- oracle的表名、字段名、constraint名的长度限制分别是多少?
文章出处:http://blog.csdn.net/haiross/article/details/38379615 Oracle:表名.字段名.constraint名的长度有限制 oracle 的命 ...
- ibatis动态的传入表名、字段名
ibatis动态的传入表名.字段名,主要传入表名和字段名的不一致. Java代码: Map<String,Object> params = new HashMap<String,Ob ...
- SQL查询表,表的所有字段名,SQL查询表,表的所有字段名
SQL查询表,表的所有字段名 2011-07-29 10:21:43| 分类: SQLServer | 标签:表 sql 字段 |举报 |字号 订阅 SQL查询表,表的所有字段名 SQ ...
随机推荐
- kubernetes 的API 介绍
在API conventions doc中描述了API的全部协议. 在API Reference文档中描述了API的端点.资源类型和示例. 在Controlling API Access doc中讨论 ...
- display:table-cell,inline-block 之间的缝隙
1.dispaly:table-call ,会让你对元素设置的为百分百的宽度失效,设置正常数值宽高时, vertical-align: middle;可让内部元素垂直居中,但如果加上position: ...
- Thinkphp5 日期与时间戳相互转换
日期转换为时间戳 $date="2013-10-01 12:23:14"; dump(strtotime($date)); //=>1380601394 时间戳 转换为日期 ...
- 逆向工程第005篇:跨越CM4验证机制的鸿沟(下)
一.前言 本文是逆向分析CM4系列的最后一篇,我会将该游戏的序列号验证机制分析完毕,进而编写出注册码生成器. 二.分析第二个验证循环 延续上一篇文章的内容,来到如下代码处: 图1 上述代码并没有特别需 ...
- Android Hook框架adbi的分析(3)---编译和inline Hook实践
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75200800 一.序言 在前面的博客中,已经分析过了Android Hook框架a ...
- Linux系统应急响应
目录 排查用户相关的信息 排查进程端口相关的信息 查找恶意程序并杀掉 斩草除根 判断入侵方式,修复漏洞 当我们被告知一台Linux服务器被黑客入侵,黑客利用该服务器进行挖矿,并且在该服务器上放置了木马 ...
- Linux-鸟菜-5-目录配置-FHS
Linux-鸟菜-5-目录配置-FHS 这节内容比较休闲,主要就是介绍Linux的目录配置,也就是那些目录通常是干啥的,这个比较重要,需要我们去了解.但是我觉得通常看一遍记不住啥,也就记个大概,主要还 ...
- 基于 registry 搭建 Docker 私有镜像仓库
今天主要介绍使用 registry 来搭建 Docker私有镜像仓库,方便在公司内部项目中使用,registry 也是 Docker 官方提供的一个镜像,操作也很简单. dockerhub: http ...
- Java_常用类API之一
Math类 Math类中包含一些对数据进行数学运算的方法,而该类中的方法全都是静态的.像这样的类称之为工具类. 1 public static int abs(int a) 2 对一个数据求绝对值 3 ...
- cms菜单栏二级折叠与交互解决方案(js)(1)
cms菜单栏二级解决方案(js) 在做一个cms系统的界面时,设计师并未指定二级菜单的交互,于是我就任意发挥,做了一个我自认为符合常规逻辑的方案 如下图 点击左上角收起按钮会收起 左侧菜单栏.中间栏左 ...