I am trying to automatically create a relationship between two test users in a migration in Django. My migration code looks like this:
# Generated manually
from django.db import migrations, transaction
from django.contrib.auth import get_user_model
def setup_test(apps, schema_editor):
User = get_user_model()
User.objects.create_superuser("admin", "[email protected]", "123")
x = User.objects.create_user(
username="x", email="[email protected]", password="123"
)
y = User.objects.create_user(
username="y", email="[email protected]", password="123"
)
UserRelatinoship = apps.get_model("myapp", "UserRelatinoship")
UserRelatinoship.objects.create(x=x, y=y, active=True)
class Migration(migrations.Migration):
dependencies = [
("myapp", "0001_initial"),
("myapp", "0002_manual"),
]
operations = [
migrations.RunPython(setup_test),
]
Model Code
from django.contrib.auth import get_user_model
User = get_user_model()
class UserRelationship(models.Model):
class Meta:
unique_together = (("x", "y"),)
x = models.ForeignKey(User, related_name="x", on_delete=models.CASCADE)
y = models.ForeignKey(User, related_name="y", on_delete=models.CASCADE)
active = models.BooleanField(default=True)
cancelled = models.BooleanField(default=False)
approved = models.BooleanField(default=False)
denied = models.BooleanField(default=False)
finalized = models.BooleanField(default=False)
def save(self, *args, **kwargs):
if self.approved:
self.active = True
if self.cancelled:
self.active = False
super().save(*args, **kwargs)
def __str__(self):
return f"{self.x}:{self.y}"
The users are created fine, but then when I try to create the relationship I get the error ValueError: Cannot assign "<User: x>": "UserRelatinoship.x" must be a "User" instance.
. Also, I can create the relationship while running the server and filling out forms manually, even though the code for that looks about identical (except it uses request.user for one part). Note I modified some names from my original code. Any help is greatly appreciated!
CodePudding user response:
You use the function setup_test
inside a migration. In a migration directly importing models will naturally not work because the current model state might be different from what the specific migration expects (See notes about Historical models in the documentation). You have used the get_user_model
function to get the user model and are using that in your function, this will simply use some functions to import the user model that you have set, hence you get the error.
Hence to fix this you need to use apps.get_model
to get the user model:
def setup_test(apps, schema_editor):
User = apps.get_model('auth', 'User')
# In case of a custom user model replace above line like below comment
# User = apps.get_model('some_app', 'CustomUserModel')
User.objects.create_superuser("admin", "[email protected]", "123")
x = User.objects.create_user(
username="x", email="[email protected]", password="123"
)
y = User.objects.create_user(
username="y", email="[email protected]", password="123"
)
UserRelatinoship = apps.get_model("myapp", "UserRelatinoship")
UserRelatinoship.objects.create(x=x, y=y, active=True)