- 基础用法
在我们的项目中,除了我们自己用的数据库节点之外,还需要访问其他部门的不少数据库。多个数据库可以在settings.DATABASES
中通过不同的名称来配置。如下:
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'my_database',
'USER': 'admin',
'PASSWORD': 'admin',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
'autocommit': True
},
},
'other': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'other_database',
'USER': 'guest_read_only',
'PASSWORD': 'guest_read_only',
'HOST': '127.0.0.1',
'PORT': '3308',
'OPTIONS': {
'autocommit': True,
},
}
这样我们就可以使用不同的连接名称来访问不同的数据库了。而在使用Django的ORM的时候呢,可以使用using()
方法来指定要访问的数据名称。
# 访问my_database, 因为database是default的数据库,所以可以用如下方式访问,(假设有个Moldel名为MyTable)
MyTable.objects.all()
# 访问other_database,
OtherTable.objects.using('other').all()
- 使用自定义Manager优化
在我们的实际应用中,由于需要访问的数据库众多,于是代码中充斥着各种using('a')
、using('b')
这样的代码,不仅看起来非常的冗余,杂乱。而且这个东西很容易忘记写或写错。经常是在调试的过程中,就一直收到数据库返回的表名不存在错误。那么应该怎样统一管理类似other_database
这样的别名呢?
models.Model.objects
其实是Django提供的一个默认的管理器Manager
。为了保证每个Model至少有一个可用的管理器。所以默认提供了objects
属性。我们就可以通过自动以管理器的方式来处理这种问题。
代码如下:
From django.db import models
# 自定义一个Manger,重写父类的get_queryset方法,
# 使返回的QuerySet均调用using方法
class MyManager(models.Manager):
def get_queryset(self):
return super(myManager, self).get_queryset().using('other')
# 定义一个抽象的Model类, 重写默认的obects属性,使用自定义的Manger
class OtherModelBase(models.Model):
objects = MyManger()
class Meta:
# 该参数表名此Model是一个仅用于继承的抽象Model
abstract = True
# 所有继承自OtherModelBase的Model,都将MyManger()作为默认的管理器
class OtherTable(OtherModelBase):
id = models.AutoField(auto_create=True)
name = models.CharField(max_length=16)
class Meta:
db_table = 'other_table'
这样使用OtherTable.objects.all()
所执行的查询,都是直接访问other_database
数据库了。在Model很多的情况下使用这种方式管理会省掉很多不必要的代码。也更加不容易出错了。