7

我需要在应用程序Question中执行模型Answer的数据迁移。在该脚本中有一个依赖项,因此我需要在应用程序Journal中创建模型Chapter的实例。因此,我将其编码如下:

def forwards(self, orm):
    for answer_object in orm.Answer.objects.all():

        #This Works.
        blog, is_created = orm['blog.Post'].objects.get_or_create(title=answer_object.answer[:100])
        blog.save()

        #This DOES NOT work
        chapter, is_created = orm['journal.Chapter'].objects.get_or_create(content_object=blog)
        chapter.save()
        #cleanup task, not relevant to this question below
        answer_object.chapter_ptr = chapter
        answer_object.save()

但正如预期的那样,这会在“ orm['journal.Chapter'].objects.get_or_create(content_object=blog)” 上引发错误,说

django.core.exceptions.FieldError: Cannot resolve keyword 'content_object' into field.

这可能是由于 content_object 是 GenericForeignKey,因此不允许某些操作。但我也尝试了其他替代方法来创建“章节”对象,例如,

chapter = orm['journal.Chapter'](content_object=blog)
ERROR > TypeError: 'content_object' is an invalid keyword argument for this function

chapter = orm.journal.Chapter(content_object=blog)
 ERROR > AttributeError: The model 'journal' from the app 'questions' is not available in this migration. (Did you use orm.ModelName, not orm['app.ModelName']?)

那么我哪里错了?任何指针表示赞赏。谢谢。

更新

因此,由于我之前的方法失败了,我尝试了一种新的策略。在上面的代码中实例化失败的模型,即Journal应用程序中的章节,我决定为此创建一个数据迁移。我还确定了我在定义中所指的模型。现在这应该是直截了当的,我想。我的转发代码如下 ---freezeforwards

def forwards(self, orm):

    for answer_object in orm['questions.Answer'].objects.all():

        #Works, AGAIN!
        blog, is_created = orm['blog.Post'].objects.get_or_create(title=answer_object.answer[:100])
        blog.save()

        # DOES NOT WORK, AGAIN!
        chapter = orm.Chapter(rank=1, content_object=blog)       
        chapter.save()

我会认为现在因为我正在创建主题应用程序(Journal )中存在的模型( Chapter )的实例,所以一切都应该解决。但我得到了同样的错误。

TypeError: 'content_object' is an invalid keyword argument for this function

它在同一点失败,即“content_object”。如果可能有帮助,我将在模型定义下方发布。

class Chapter(models.Model):

    rank = models.IntegerField()

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

更新 2 想补充一点,这些转发方法中涉及的所有模型,即 - 博客、章节、问题;在 South 的 schemamigration 创建的 00n_*.py 文件中完全定义。

4

4 回答 4

8

在获得 Rob 和 South & Django 用户组的人们的帮助后,我能够解决这个问题。下面是我的forwards数据迁移脚本的定义。

def forwards(self, orm):

    for answer_object in orm['questions.Answer'].objects.all():


        blog, is_created = orm['blog.Post'].objects.get_or_create(title=answer_object.answer[:100])
        blog.save()

        #I have to manually lookup the content_type ans set it in the chapter creation.
        ct = orm['contenttypes.ContentType'].objects.get(app_label="blog", model="post")    
        chapter = orm.Chapter(rank=1, content_type=ct, object_id=blog.id)

        chapter.save()
于 2011-08-13T19:03:44.620 回答
1

在这里Django South: Creating schemamigration for more than one app之前已经回答了这个问题

基本上南方目前不支持多个应用程序。

如果您不想让您的应用程序更加复杂,我会在 db.execute 中使用原始 SQL 作为快速修复。

看起来博客和期刊是非常相互关联的。您确定要将它们放在单独的应用程序中吗?

于 2011-08-08T01:05:40.387 回答
0

为了通过 manage.py 创建迁移,将 --freeze=other_app 作为参数传递以将此 other_app 的模型定义添加到迁移本身。

于 2014-01-31T16:26:44.657 回答
0

这是对 Chantz 回答的评论,对我来说效果很好(没有代表将此作为评论发布)

为了节省一些其他时间,您还需要在创建迁移时冻结 contenttype 应用程序:

python manage.py datamigration yourapp migrationname --freeze contenttypes
于 2014-10-20T22:06:30.407 回答