Ошибка переноса данных 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 ...
Я никогда не сталкивался с этой проблемой раньше, поэтому, пожалуйста, прочитайте оригинальный пост для более подробной информации, надеюсь, это поможет.