I have a model `UserProfile` which looks like this:
{{{
class UserProfile(VStandardModel):
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, null=True, default=None)
mail = models.TextField(null=True, default=None, unique=True)
}}}
And I want to make migration which will do two things:
1. Change user field to `user =
models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
null=False)`
2. If user was `None` set a user with an email
So I wrote a migration:
{{{
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth import get_user_model
import django.db.models.deletion
def empty_users(apps, schema_editor):
UserProfile = apps.get_model('main', 'UserProfile')
model_user = get_user_model()
for profile in UserProfile.objects.all().only('user', 'mail'):
if profile.user is None:
try:
profile.user = model_user.objects.get(email=profile.mail)
except model_user.DoesNotExist:
try:
profile.user =
model_user.objects.create(email=profile.mail, is_active=False)
except Exception as err:
print(err)
profile.save()
class Migration(migrations.Migration):
dependencies = [
('main', '0066_auto_20180222_1954'),
]
operations = [
migrations.RunPython(empty_users,
reverse_code=migrations.RunPython.noop),
migrations.AlterField(
model_name='userprofile',
name='user',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL),
),
]
}}}
And, as you see, I emphasized an error in `except Exception as err:`. It
is: `Cannot assign "<User: >": "UserProfile.user" must be a "User"
instance.`.
But if I change `UserProfile = apps.get_model('main', 'UserProfile')` to
`from main.models import UserProfile` migration will pass.
--
Ticket URL: <https://code.djangoproject.com/ticket/29283>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => invalid
Comment:
Hello there,
Without going into all the details you can't mix migration defined models
with application defined ones. When writing `RunPython` executors you must
'''always''' use the provided `apps.get_model` method to retrieve models.
In your particular case `get_user_model()` is going to return an
application defined model class and not a migration one; you should use
`apps.get_model(settings.AUTH_USER_MODEL)` instead.
In there future please avoid using this ticket tracker as a support
channel TicketClosingReasons/UseSupportChannels.
--
Ticket URL: <https://code.djangoproject.com/ticket/29283#comment:1>