【问题标题】:No fixture named 'X' found找不到名为“X”的夹具
【发布时间】:2014-01-11 15:22:59
【问题描述】:

我使用的是 Django 1.6,我使用 South 来处理迁移。 在我的大部分应用程序中,我曾经有 initial_data.json 文件。我将它们转换为使用迁移而不是由 Django 自动加载(如文档中推荐的那样)

当我遇到一个奇怪的行为/错误时,我正在使用 South 的 0.8.2 版本,其中加载夹具是根据模型代码而不是迁移状态完成的。我看到最新版本(0.8.4)已经添加了一些与loaddata相关的错误修复,所以我升级到它。

现在我在加载固定装置的所有迁移中都收到以下错误:

UserWarning: No fixture named 'X' found. 

当我使用 Django 的 loaddata 时,它工作正常。关于如何解决这个问题的任何想法?

【问题讨论】:

  • 您能否澄清一下“将它们转换为加载迁移”,您对固定装置做了什么?你能在一个新项目中重现这个问题吗?

标签: django django-south


【解决方案1】:

South and fixtures

South 只需修补 syncdb 以跳过具有迁移的模型的夹具加载,并在运行应用的最终迁移后实际加载它们。

确保您的 initial_data 文件位于正确的位置

加载initial_data并不需要你实际做某事,而是将fixtures放在the correct place as explained in Django's documentation中。

引用文档:

默认情况下,Django 会在每个应用程序内的 fixtures 目录中查找 固定装置。您可以将 FIXTURE_DIRS 设置设置为附加列表 Django 应该查看的目录。

这意味着如果您有一个名为“myapp”的应用程序,您将在其中创建一个“fixtures”目录并将 json 放在那里,例如:myproject/myapp/fixtures

Django 1.7 及更新版本

Django 1.7 introduced built-in migrations。它们有一个类似于 South 的界面;用于创建迁移makemigrations、运行它们migrate 等的管理命令。

但是,initial_data 装置不再在 syncdb 运行时自动加载;除非它是现有的应用程序,并且没有迁移。这是mentioned in the release notes

文档现在建议创建一个datamigration 来处理夹具加载。幸运的是,这很容易做到,这就是我通常的做法:

1。创建一个empty data migration

$ python manage.py makemigrations --empty myapp

如果您只有初始迁移,您最终会得到这些文件(请注意,为了清楚起见,我将迁移 0002 重命名):

myapp/
├── __init__.py
├── fixtures
│   └── my_initial_data.json
└── migrations
    ├── 0001_initial.py
    ├── 0002_load_fixture.py
    └── __init__.py

2。更新0002_load_fixture.py的代码运行loaddata

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations
from django.core.management import call_command


def load_my_initial_data(apps, schema_editor):
    call_command("loaddata", "my_initial_data.json")


class Migration(migrations.Migration):
    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(load_my_initial_data),
    ]

【讨论】:

  • 是的,理论上。我在“fixtures”文件夹中有一个名为 initial_data.json 的文件,并尝试将此文件夹移动到:project_rootproject_root/app_rootproject_root/app_root/app,但没有任何乐趣(Django 1.8 btw)。每次我为应用程序运行测试时仍然会出现此错误。
  • 好吧,这是个谎言。它真的在寻找以下之一:根项目文件夹中的initial_data[.default].[xml|yaml|json][.zip|.gz|.bz2]。 (附言我实际上使用的是 Django 1.9)
  • 所以 1.8 的文档是错误的,而 1.7 的注释也是错误的,因为我使用的是 1.9,并且在您运行测试时它仍然会加载 initial_data?
  • 这里声明:docs.djangoproject.com/en/1.9/howto/initial-data“Django 在每个应用程序内的固定装置目录中查找固定装置”。我发现情况并非如此,并查看了代码并发现(见上文):“它确实在寻找以下之一:initial_data[.default].[xml|yaml|json][.zip|.gz|.bz2]在根项目文件夹中”。因此文档是错误的,并没有说明它实际上做了什么。你想让我问:“为什么 Django 文档有问题?”?
  • 对于谁对答案投了反对票,请评论什么是不正确的?
【解决方案2】:

那你为什么不在你的迁移中运行 loaddata 命令呢?

import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models

class Migration(DataMigration):

    def forwards(self, orm):
        from django.core.management import call_command
        call_command("loaddata", "my_fixture.json")

【讨论】:

  • 这对我来说也失败了。
【解决方案3】:

如果您仍然收到错误:

找不到名为“X”的夹具

尝试使用 json 文件的路径,因为 manage.py 可能不是从项目目录运行(它甚至可能从根目录运行)。试试这样的:

import os

app_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))
json_path = os.path.join(app_path, 'fixtures', 'my_fixture.json')
call_command("loaddata", json_path)

【讨论】:

    【解决方案4】:

    当文件名不包含“.json”扩展名时也会发生此错误。

    为了从当前工作目录加载一个fixture,它必须以'.json'结尾。

    【讨论】:

      猜你喜欢
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      相关资源
      最近更新 更多