GenericForeignKey data migtation error: 'content_object' is an invalid keyword argument

时间:2015-10-31 00:06:49

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

I want to create data migrations for a model(Comment) which has a GenericForeignKey relation. My model was made according to django documentation for contenttypes. Models: ... 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') Data migration: ... 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) ] When I run ./manage.py migrate I get: TypeError: 'content_object' is an invalid keyword argument for this function I have to say that I have used same code as create_comment inside a view and works well. Im using django 1.7.7. Im not using south. Edit: I tried Shang Wang's answer. 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 ) Is not working either: ValueError: Cannot assign "<ContentType: nice meme>": "Comment.content_type" must be a "ContentType" instance.

3 个答案:

答案 0 :(得分:10)

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

您确实需要将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
    )

答案 1 :(得分:0)

请试试这个:

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对象。

编辑:

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

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

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

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

之前我从未遇到过这个问题,所以请阅读原帖以获取更多详情,希望这会有所帮助。

答案 2 :(得分:0)

我遇到了同样的问题,解决方法是使用小写的模型名称获取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
    )