Search code examples
djangodjango-migrations

Can't create object inside migrations


I'm extending django.contrib.auth.User model with my model:

class Farmer(models.Model):
    user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, related_name="farmer")
    mob_phone = models.CharField(max_length=12)

I want to create some of these Farmer instances during migrations, so i have a python-migration job, which goes after all other migrations :

def create_farmers(apps, schema_editor):
    db_alias = schema_editor.connection.alias
    Farmer = apps.get_model("farmer", "Farmer")
    User = get_user_model()

    u = User.objects.using(db_alias).create(username="kek" ,password="lol")
    farmer = Farmer.objects.using(db_alias).create(id=1, user=u, mob_phone="1")

I run this job in operations section just like all other migrations:

operations = [
    migrations.RunPython(create_farmers, revert_create_farmers),
]

But Django is laughing in my face with

ValueError: Cannot assign "<User: kek>": "Farmer.user" must be a "User" instance.

This is knocking me off, because u is definitely as User instance!


Solution

  • I made my migration work - not sure if it's legitimate way. Anyway, here's my wisdom.

    When you use apps.get_model("<app>", "<Model>") in migration operations, django seems to import not an exact <Model>, but something like a <Model>. I made this conclusion, when reading the django sources for class inside migrations. Inside that sources i found an assert, which is comparing my forignKey User type with type _fake.User. Of course my real User of type django.contrib.auth.models.User is not the same as _fake.User, and django through that partially incorrect message: ValueError: Cannot assign "<User: kek>": "Farmer.user" must be a "User" instance.

    The solution was to import a real Farmer model from the app - not to user the apps.get_model("<app>", "<Model>") method