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