【问题标题】:GenericForeignKey data migtation error: 'content_object' is an invalid keyword argumentGenericForeignKey 数据迁移错误:“content_object”是无效的关键字参数
【发布时间】:2016-01-31 12:08:13
【问题描述】:

我想为具有GenericForeignKey 关系的模型(Comment) 创建数据迁移。我的模型是根据django documentationcontenttypes 制作的。

型号:

...
class NiceMeme(models.Model):
    """
        Example model.
    """

    name = models.CharField(max_length=140)
    image = models.ImageField(upload_to=get_path_to_store_nice_meme_images)


class Comment(models.Model):
    """
        Model to add comments to any other (non abstract) model.
    """
    ...
    user = models.ForeignKey(ExtendedUser)
    content = models.CharField(max_length=140)
    content_type = models.ForeignKey(ContentType)
    object_pk = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_pk')

数据迁移

...
def create_comment(apps, schema_editor):
    ...
    nice_meme = NiceMeme.objects.create(name='Nice nice meme')
    Comment.objects.create(
        user=user,
        content='Gott ist tot',
        poster_username='Friedrich',
        content_object=nice_meme
    )

...
operations = [
    migrations.RunPython(create_comment)
]

当我运行./manage.py migrate 时,我得到:

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

我不得不说,我在视图中使用了与create_comment 相同的代码并且运行良好。

我正在使用 django 1.7.7。我没有用南。

编辑: 我试过尚王的答案。

Comment.objects.create(
    user=user,
    content='Gott ist tot', 
    poster_username='Friedrich',
    content_type=ContentType.objects.get_for_model(nice_meme),
    object_pk=nice_meme.id
) 

也不行:

ValueError: Cannot assign "<ContentType: nice meme>": "Comment.content_type"  must be a "ContentType" instance.

【问题讨论】:

  • 我也有同样的问题,使用 Django 1.8.3 :/
  • 你检查答案了吗?
  • 对不起。我正在休假。我会在几个小时内看看它。谢谢。

标签: python django django-migrations generic-foreign-key


【解决方案1】:

正如我所说,我也遇到过同样的问题,一位同事帮助我解决了这个问题:

你确实需要设置content_typeobject_pk,正如+Shang Wang指出的那样,但是ContentType必须使用apps.get_model加载而不是直接导入。

所以用这个:

ContentType = apps.get_model('contenttypes', 'ContentType')

在您的迁移方法中,一切都应该工作:)

def create_comment(apps, schema_editor):
    ...
    ContentType = apps.get_model('contenttypes', 'ContentType')
    nice_meme = NiceMeme.objects.create(name='Nice nice meme')
    Comment.objects.create(
        user=user,
        content='Gott ist tot',
        poster_username='Friedrich',
        content_type=ContentType.objects.get_for_model(nice_meme),
        object_pk=nice_meme.id
    )

【讨论】:

  • 不是这样工作的。 ContentType.objects 实际上是 django.db.models.manager.Manager 所以我所做的是:nice_meme_contenttype = ContentType.objects.get( app_label='comments', model='nicememe' ) 型号名称必须小写。现在正在工作:)
  • 奇怪的@LaraChícharo ...您是否使用apps.get_model加载了ContentType?我很高兴你解决了你的问题顺便说一句:)
【解决方案2】:

请试试这个:

from django.contrib.contenttypes.models import ContentType

nice_meme = NiceMeme.objects.create(name='Nice nice meme')
Comment.objects.create(user=user,
                       content='Gott ist tot', 
                       poster_username='Friedrich',
                       content_type=ContentType.objects.get_for_model(nice_meme),
                       object_pk=nice_meme.id)

我认为问题在于您的 content_object 字段只是您的 Comment 模型对象快速访问外键的简单方法,例如:

obj = some_comment.content_object

它不是一个实际的字段,而是 2 个字段的组合,因此您不能直接为其分配一个 NiceMeme 对象。

编辑:

听起来您正在使用 South,here 描述了一个问题。该解决方案在另一个 SO thread 中得到解答。听起来解决方案是冻结与您的迁移相关的任何模型:

python manage.py schemamigration --auto yourapp --freeze contenttypes

您可能需要冻结更多应用:

python manage.py schemamigration --auto yourapp --freeze contenttypes --freeze someotherapp ...

我以前从未遇到过这个问题,所以请阅读原帖了解更多详细信息,希望对您有所帮助。

【讨论】:

  • 感谢您的回答。不幸的是,我得到了这个:ValueError: Cannot assign "&lt;ContentType: nice meme&gt;": "Comment.content_type" must be a "ContentType" instance.
  • 我更新了我的答案,我没有足够的知识来处理这个问题,但是试试我找到的线程看看它是否有帮助。
  • 我不使用南,我使用 django 1.7.7。很抱歉直到现在才告诉你。感谢您的帮助。
【解决方案3】:

我也遇到了同样的问题,解决办法是获取ContentType对象,模型名小写:

content=ContentType.objects.get(app_label='appname', model='modelname')

对于这个问题:

def create_comment(apps, schema_editor):
    ContentType = apps.get_model('contenttypes', 'ContentType')    
    nice_meme = NiceMeme.objects.create(name='Nice nice meme')

    Comment.objects.create(
        user=user,
        content=ContentType.objects.get(app_label='appname', model='nicememe')
        poster_username='Friedrich',
        content_object=nice_meme
    )

【讨论】:

    猜你喜欢
    • 2019-05-17
    • 2013-07-13
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2017-05-04
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多