在 Django 1.7 之前,当使用 Django Sites Framework 时,可以/应该使用 Initial Fixtures 定义初始数据。
[
{
"pk": 1,
"model": "sites.site",
"fields": {
"domain": "domain1",
"name": "name1"
}
},
{
"pk": 2,
"model": "sites.site",
"fields": {
"domain": "domain2",
"name": "name2"
}
},
{
"pk": 3,
"model": "sites.site",
"fields": {
"domain": "domain3",
"name": "name3"
}
}
]
由于它是全局项目设置,所以我在项目根目录中添加了一个“fixtures”文件夹,并将其添加到FIXTURE_DIRS。
# Used to search fixture files directories.
# Fixture files are files that provide initial data to be
# inserted in the database. (>python manage.py loaddata)
FIXTURE_DIRS = [
os.path.join(PROJECT_ROOT, "fixtures"),
]
现在,我使用的是 Django 1.7,建议使用 migrations。引用 Django 文档:
要为您的项目设置正确的名称和域,您可以使用数据迁移。
问题是迁移是特定于应用程序的:
python manage.py makemigrations --清空你的应用程序名称
那么,使用数据迁移将站点信息添加到我的项目的推荐方法是什么?这个迁移应该住在哪里?
运行
python manage.py makemigrations --empty sites
会在第三方应用程序文件夹中创建迁移,所以我们不希望这样。
不应该定义 MIGRATION_DIRS 因为初始数据存在 FIXTURE_DIRS 吗?
我在设置文档中找到了MIGRATION_MODULES,但问题仍然存在,它是特定于应用程序的。
首先,在 django 设置中配置
MODULE_MIGRATIONS
:
MIGRATION_MODULES = {
'sites': 'myproject.fixtures.sites_migrations',
}
然后,运行
./manage.py makemigrations sites
让 django 创建目录并在 0001_intitial.py
包中创建 myproject.fixtures.sites_migrations
。
然后,做
./manage.py makemigrations --empty sites
。迁移文件应该在指定的包中创建。
我的文件
0002_initialize_sites.py
看起来像这样:
from __future__ import unicode_literals
from django.db import migrations
def insert_sites(apps, schema_editor):
"""Populate the sites model"""
Site = apps.get_model('sites', 'Site')
Site.objects.all().delete()
# Register SITE_ID = 1
Site.objects.create(domain='create.tourtodo.com', name='create')
# Register SITE_ID = 2
Site.objects.create(domain='www.tourtodo.com', name='www')
class Migration(migrations.Migration):
dependencies = [
('sites', '0001_initial'),
]
operations = [
migrations.RunPython(insert_sites)
]
您只需将编号最高的
sites
迁移引用为依赖项即可。
def forward(apps, schema_editor):
Site = apps.get_model("sites", "Site")
db_alias = schema_editor.connection.alias
s, created = Site.objects.using(db_alias).get_or_create(pk=1)
s.name = APP_NAME
s.domain = APP_NAME
s.save()
def reverse(apps, schema_editor):
Site = apps.get_model("sites", "Site")
db_alias = schema_editor.connection.alias
s = Site.objects.using(db_alias).get(pk=1)
s.name = ORIG_APP_NAME
s.domain = ORIG_APP_NAME
s.save()
class Migration(migrations.Migration):
dependencies = [
# `core` is the app containing this migration
('core', '0001_initial'),
# `0002_alter_domain_unique` is the highest-numbered migration for
# the sites framework
('sites', '0002_alter_domain_unique'),
]
operations = [
migrations.RunPython(forward, reverse)
]
这是在 Django 1.11.2 上测试的。
Fwiw,上面的
MODULE_MIGRATIONS
解决方案对我不起作用。
对@Jason 的答案进行了一些调整。 最后使用 Django 2.2 进行了测试。
from django.conf import settings
from django.db import migrations
def update_site_domain(apps, schema_editor):
Site = apps.get_model("sites", "Site")
s, _ = Site.objects.get_or_create(pk=settings.SITE_ID)
s.domain = settings.HOST
s.save()
class Migration(migrations.Migration):
dependencies = [
("your_app", "last_migration_name"),
("sites", "0002_alter_domain_unique"), # highest-numbered migration for the sites framework
]
operations = [migrations.RunPython(update_site_domain)]