Data Migration produces ValueError that must be "User" instance but it is?

Viewed 340

I'm trying to add a staff member to the database. I'm doing this via a data migration. I am able to add a User through the migration but I'm not able to assign it to user_id of the StaffPosition I am trying to create. The error I get is a ValueError that says I need to use a "User" instance but I thought I was doing that.

I've used ipdb to troubleshoot this and look at what the values of some properties are. I've also tried grabbing user different ways, such as with the pk or id of the User instance. Another thing I did was comment out all lines of code in create_urechr_user except for the section that creates the User object. With that, I was able to successfully add the User to the database. But I'm unable to make my StaffPosition's user_id that User.

# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2019-02-08 21:23
from __future__ import unicode_literals

from django.db import migrations
from django.contrib.auth.models import User

def create_urechr_user(apps, schema_editor):
    staffPosition = apps.get_model("hr", "staffPosition")
    User.objects.create_user(
         username = "myName",
         password = "test",
         is_active = True,
         email = "",
    )
    staff = staffPosition.objects.get(pk = 95)
    user = User.objects.get(username = "myName")


    staffPosition.objects.create(
        parent_staff_position = staff,
        user_id = user,
        title = "Testing Title",
    )

class Migration(migrations.Migration):

    dependencies = [
        ('hr', '0003_add_verbose_name_20190213_1519'),
    ]

   operations = [
        migrations.RunPython(create_urechr_user),
    ]

ValueError: Cannot assign "<User: urechr>": "StaffPosition.user_id" must be a "User" instance.

1 Answers

The reason for this error is that you mix migration defined model with application defined model. Specifically, you import your User model from the application and you're getting the staffPosition as apps.get_model.

You have to get both models with apps.get_model instead of using from django.contrib.auth.models import User:

from django.conf import settings

def create_urechr_user(apps, schema_editor):
    staffPosition = apps.get_model("hr", "staffPosition")

    # Here we get the user model the right way
    User = apps.get_model(settings.AUTH_USER_MODEL)
    User.objects.create_user(
         username = "myName",
         password = "test",
         is_active = True,
         email = "",
    )
    staff = staffPosition.objects.get(pk = 95)
    user = User.objects.get(username = "myName")


    staffPosition.objects.create(
        parent_staff_position = staff,
        user = user,
        title = "Testing Title",
    )

You can read about AUTH_USER_MODEL here: https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-AUTH_USER_MODEL

You can also check this ticket in a django bugtracker with a similar issue to yours: https://code.djangoproject.com/ticket/29283

Looks like there's an opportunity for making Django errors reporting more user friendly :)

Related