自从我上次回答以来,Django 弃用并删除了pre_syncdb 信号。我已经更新了答案以适应更新的版本。新版本的基本机制是相同的,因为这两种方法都依赖于信号和仅在 HSTORE 扩展不存在时执行的 SQL 代码。
Django 1.8+
自从 Django 引入数据库迁移以来,pre_syncdb 信号为marked deprecated in 1.7 和completely removed in 1.9。但是,他们引入了一个名为pre_migrate 的新信号,可以以相同的方式使用。
"""
This is an example models.py which contains all model definition.
"""
from django.dispatch import receiver
from django.db import connection, models
from django.db.models.signals import pre_migrate
import sys
# The sender kwarg is optional but will be called for every pre_syncdb signal
# if omitted. Specifying it ensures this callback to be called once.
@receiver(pre_migrate, sender=sys.modules[__name__])
def setup_postgres_hstore(sender, **kwargs):
"""
Always create PostgreSQL HSTORE extension if it doesn't already exist
on the database before syncing the database.
Requires PostgreSQL 9.1 or newer.
"""
cursor = connection.cursor()
cursor.execute("CREATE EXTENSION IF NOT EXISTS hstore")
# ...rest of your model definition goes here
class Foo(models.Model):
# ...field definitions, etc.
Django 1.6+(原始答案)
我的建议是使用pre_syncdb 信号挂钩。
在另一个 question 上查看我的回答。
"""
This is an example models.py which contains all model definition.
"""
from django.dispatch import receiver
from django.db import connection, models
from django.db.models.signals import pre_syncdb
import sys
# The sender kwarg is optional but will be called for every pre_syncdb signal
# if omitted. Specifying it ensures this callback to be called once.
@receiver(pre_syncdb, sender=sys.modules[__name__])
def setup_postgres_hstore(sender, **kwargs):
"""
Always create PostgreSQL HSTORE extension if it doesn't already exist
on the database before syncing the database.
Requires PostgreSQL 9.1 or newer.
"""
cursor = connection.cursor()
cursor.execute("CREATE EXTENSION IF NOT EXISTS hstore")
# ...rest of your model definition goes here
class Foo(models.Model):
# ...field definitions, etc.
pre_syncdb 信号在模型表创建之前被触发,因此非常适合在每次设置测试数据库时确保安装扩展。 IF NOT EXISTS 确保 PostgreSQL 在已安装扩展程序时忽略该命令。如果您在已存在的扩展程序上运行 CREATE EXTENSION,则会收到错误消息。
这适用于默认的 Django 单元测试框架,并且很可能适用于 Django 鼻子测试。
有关信号的更多信息:
https://docs.djangoproject.com/en/1.6/ref/signals/#management-signals