17

在 Django 1.7 之前,当使用Django Sites Framework时,可以/应该使用Initial Fixtures定义初始数据。

myproject/fixtures/initial_data.json

[
{
    "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 --empty yourappname

那么,使用数据迁移将站点信息添加到我的项目的推荐方法是什么?这种迁移应该住在哪里?

运行python manage.py makemigrations --empty sites会在第三方应用程序文件夹中创建迁移,所以我们不希望这样。

不应该将 MIGRATION_DIRS 定义为初始数据存在的 FIXTURE_DIRS 吗?

我在设置文档中找到了MIGRATION_MODULES,但问题仍然存在,它是特定于应用程序的。

4

3 回答 3

16

首先,MODULE_MIGRATIONS在您的 django 设置中进行配置:

MIGRATION_MODULES = {
    'sites': 'myproject.fixtures.sites_migrations',
}

然后,运行./manage.py makemigrations sites让 django 创建目录并0001_intitial.pymyproject.fixtures.sites_migrations包中创建。

然后,做./manage.py makemigrations --empty sites。迁移文件应该在指定的包中创建。

我的文件0002_initialize_sites.py如下所示:

-*- coding: utf-8 -*-
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)
    ]
于 2014-11-15T15:20:37.913 回答
6

您只需要将编号最高的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上面的解决方案对我不起作用。

于 2017-06-27T06:58:46.830 回答
0

对@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)]
于 2019-11-19T19:58:42.513 回答