Opened 8 years ago
Closed 8 years ago
#29283 closed Bug (invalid)
Difference between 'apps.get_model' and 'import' in migration
| Reported by: | bronvic | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.11 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
HTR:
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:
- Change user field to
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=False) - If user was
Noneset 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.
Note:
See TracTickets
for help on using tickets.
Hello there,
Without going into all the details you can't mix migration defined models with application defined ones. When writing
RunPythonexecutors you must always use the providedapps.get_modelmethod to retrieve models. In your particular caseget_user_model()is going to return an application defined model class and not a migration one; you should useapps.get_model(settings.AUTH_USER_MODEL)instead.In there future please avoid using this ticket tracker as a support channel TicketClosingReasons/UseSupportChannels.