Ошибка переноса данных GenericForeignKey: 'content_object' является недопустимым аргументом ключевого слова

Я хочу создать миграцию данных для модели (Comment) который имеет GenericForeignKey связь. Моя модель была сделана в соответствии с документацией Django для типов контента.

Модели:

...
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.

3 ответа

Как я уже сказал, я прошел через эту же проблему, и коллега помог мне с этим советом:

Вам действительно нужно установить content_type а также object_pk как указал + Шан Ван, но 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 с именем модели в нижнем регистре:

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
    )

Пожалуйста, попробуйте это:

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 возражать против этого.

Редактировать:

Похоже, вы используете Юг, здесь описана проблема. Решение получено в другой ветке SO. Похоже, решение состоит в том, чтобы заморозить любую модель, с которой связана ваша миграция:

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

Возможно, вам придется заморозить больше приложений:

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

Я никогда не сталкивался с этой проблемой раньше, поэтому, пожалуйста, прочитайте оригинальный пост для более подробной информации, надеюсь, это поможет.

Другие вопросы по тегам