Dealing GenericRelation and GenricForeignKey inside migrations
Asked Answered
R

1

5

I have models with GenricForeigKey and GenericRelation fields.

class Datasheet(models.Model):
    package1 = GenericRelation('PackageInstance')
    ...

class PackageInstance(models.Model):
    content_object = GenericForeignKey()
    object_id = models.PositiveIntegerField(null=True)
    content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE)
    ....

I am migrating from another models, inside my migration I want to create new instance.

    for ds in Datasheet.objects.all():
        pi = PackageInstance.objects.create(content_object=ds)

However this fails

TypeError: DesignInstance() got an unexpected keyword argument 'content_object'

Additionally, ds.package1.all() will also fail.

AttributeError: 'Datasheet' object has no attribute 'package1'

How do I solve this?

Retrogressive answered 12/4, 2020 at 1:50 Comment(2)
R
8

I did some research but did not find a direct answer to my question. The most important thing to remember is that model methods will not be available in migrations. This includes fields created by the Content Types framework. However, object_id and content_type will be there.

My solution is to simply create things by hand.

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

Datasheet = apps.get_model('api', 'Datasheet')
DatasheetContentType = ContentType.objects.get(model=Datasheet._meta.model_name, app_label=Datasheet._meta.app_label)

for ds in Datasheet.objects.all():
    di = DesignInstance.objects.create(object_id=ds.id, content_type=DatasheetContentType)
Retrogressive answered 12/4, 2020 at 1:50 Comment(1)
I'd suggest using ContentType.objects.get_for_model(Datasheet) instead, as it will automatically create missing content types and clear the cache.Acanthaceous

© 2022 - 2024 — McMap. All rights reserved.