同步model的权限语句
migrate [<app_label> [<migrationname>]]
官网文档: https://docs.djangoproject.com/en/1.8/ref/django-admin/#migrate-app-label-migrationname
添加Djando自定义权限
添加的时候,在model的meta里面添加
class Task(models.Model):
...
class Meta:
# 三个自定义权限
permissions = (
("view_task", "Can see available tasks"),
("change_task_status", "Can change the status of tasks"),
("close_task", "Can remove a task by setting its status as closed"),
)
connection_name = 'mipay'
然后执行:
python manage.py migrate
按官网的文能说,这样就能同步权限,但是我执行这个命令并没有产生任何效果。
原因是,这个命令还有一个可选参数 --database , 如果不填的话默认default, 这个是settings.py里面的DATABASES配置里面默认的那个配置,也是数据库映射别名(alias)
所以刚才这个命令,只是会对default 的数据库(也就是我们业务的owan数据库产生效果)
然后我下面加上数据库参数, 因为这个表是mipay数据库的,我加上--database=mipay
python manage.py migrate --database=mipay
依然不生效,为什么不是已经指定DB了吗,为什么还不生效,auth_permission还是没有新增权限记录。
查了很久才发现,这个--database是指定要插入数据的DB,而不是这个model所属的DB,现在我们是要插入auth_permission表,那么这个表是属于owan_admin这个DB的,所以--database要执行这个DB才生效,settings里面admin是owan_adminDB的配置alias,
所以最后执行这个命令成功更新了权限
python manage.py migrate --database=admin
延伸:Django 多DB路由
上面我们的model定义的时候,会用一个类属性connection_name来指定model所属的DB,注意,
这个connection_name不是Django提供的指定DB的字段,之所以我们可以这样指定,是因为我们注册了一个DB的router ,参考文档:https://docs.djangoproject.com/en/2.0/topics/db/multi-db/)
这个router主要包括三个方法
- db_for_read 根据model选择读的DB
- db_for_write 根据model选择写的DB
- allow_migrate 根据model选择是否允许migrate
对于读逻辑: 如果model类定义有connection_name属性,那么它的主DB就是这个,从DB就是这个属性后面拼接_slave,读的时候,读从库。比如connection_name=mipay, 那么读的时候会读mipay_slave这个DB setting。
对于写逻辑:直接写进connection_name属性这个主库DB
事例
# from django.db import connections
from django.conf import settings
ADMIN_DATABASE_PREFIX_LIST = ["django", "utils", "auditlog"]
class DBRouter(object):
"""可以按照model里面的connection_name来设置要读的数据库"""
def db_for_read(self, model, **hints):
# 对于django内置的表,全部使用另外一个表
db_name = None
prefix = model.__module__.split('.')[0]
if prefix in ADMIN_DATABASE_PREFIX_LIST:
db_name = settings.ADMIN_DATABASE
# 如果有配置从库,使用从库进行读操作
if settings.READ_FROM_SLAVE:
slave_db_name = "%s_slave" % db_name
if slave_db_name in settings.DATABASES:
db_name = slave_db_name
elif hasattr(model, 'connection_name'):
db_name = model.connection_name
# 如果有配置从库,使用从库进行读操作
if settings.READ_FROM_SLAVE:
slave_db_name = "%s_slave" % model.connection_name
if slave_db_name in settings.DATABASES:
db_name = slave_db_name
elif not hasattr(model, 'connection_name'):
if 'default_slave' in settings.DATABASES:
db_name = 'default_slave'
return db_name
def db_for_write(self, model, **hints):
db_name = 'default'
prefix = model.__module__.split('.')[0]
if prefix in ADMIN_DATABASE_PREFIX_LIST:
db_name = settings.ADMIN_DATABASE
elif hasattr(model, 'connection_name'):
db_name = model.connection_name
return db_name
def allow_migrate(self, db, app_label, model_name=None, **hints):
model = hints.get("model")
#print model_name, type(model_name)
if model_name == 'recharge':
print db
if not model:
return False
prefix = model.__module__.split('.')[0]
if prefix in ADMIN_DATABASE_PREFIX_LIST:
if db == settings.ADMIN_DATABASE:
return True
else:
return False
elif hasattr(model, 'connection_name'):
if model.connection_name == db:
return True
else:
return False
else:
if db == "default":
return True
else:
return False
return None
写完这个router记得要在setting里面加上配置,注册这个router
DATABASE_ROUTERS = [
'utils.db.router.DBRouter'
]
网友评论