Skip to content Skip to sidebar Skip to footer

Why Genericrelation Fields Does Not Work In Data Migrations(django)

I want to make data migration in order to add user read post in database. There is such code: def user_read_posts(apps, schema_editor): User = apps.get_model('main', 'User')

Solution 1:

In RunPython migration scripts apps.get_models() will get historical version of models, not the latest django models you have in source. These historical models are quite limited. Excerpt from django documentation:

historical models will not have any custom methods that you have defined. They will, however, have the same fields, relationships, managers (limited to those with use_in_migrations = True) and Meta options (also versioned, so they may be different from your current ones).

But that does not mean that you can't use latest and fully functional models by just importing them and using them. In that case you are risking that the migration script won't run correctly in the future - since latest version of model can change (e.g. model method can be renamed, deleted, logic changed etc.). So, it is possible but you need to be aware of the risk using models like this.

Content types framework is pretty old and rarely changed django contrib application and IMHO it is safe enough to use it like this.

Inspired by the answer and solution I made and use, I have made following draft I hope you will find useful:

defuser_read_posts(apps, schema_editor):
    User = apps.get_model("main", "User")
    Post = apps.get_model("main", "Post")
    Comment = apps.get_model("comments", "Comment")

    from django.contrib.contenttypes.models import ContentType

    comments = Comment.objects.all()
    for comment in comments:
        try:
            # assuming that Comment has object_id field holding reference to PK# of the referenced object 
            ct = ContentType.objects.get(model=comment.content_type.model, 
                                         app_label=comment.content_type.app_label)
            content_object = ct.get_object_for_this_type(pk=comment.object_id)
        except Exception, ex: 
            # TODO: can happen if some content type / model is deleted.continueprint (content_object.__class__.__name__)
        ifisinstance(content_object, Post):
            # TODO: maybe you will need to copy/adapt read_posts.add method's logic here
            comment.user.read_posts.add(content_object)

Post a Comment for "Why Genericrelation Fields Does Not Work In Data Migrations(django)"