I'm trying to work on a Django project on a different computer than the one I usually do. However, when trying to run the following migration:
from django.conf import settings
import django.contrib.postgres.fields
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0010_auto_20180727_1345'),
('lucy_web', '0183_auto_20180814_1505'),
]
operations = [
migrations.CreateModel(
name='GoogleCredentials',
fields=[
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.OneToOneField(limit_choices_to={'is_staff': True}, on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
('token', models.CharField(max_length=255, null=True)),
('refresh_token', models.CharField(max_length=255, null=True)),
('token_uri', models.CharField(max_length=255, null=True)),
('client_id', models.CharField(max_length=255, null=True)),
('client_secret', models.CharField(max_length=255, null=True)),
('scopes', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=255), null=True, size=None)),
],
options={
'abstract': False,
},
),
]
I get this error message:
django.db.migrations.exceptions.NodeNotFoundError: Migration lucy_web.0184_googlecredentials dependencies reference nonexistent parent node ('auth', '0010_auto_20180727_1345')
Following https://groups.google.com/forum/#!topic/django-users/m59NufO1GI8, I went into the django/contrib/auth/migrations
directory and found that indeed, there are 9 migrations, but the 10th migration is not there:
Kurts-MacBook-Pro:auth kurtpeek$ ls migrations
0001_initial.py
0002_alter_permission_name_max_length.py
0003_alter_user_email_max_length.py
0004_alter_user_username_opts.py
0005_alter_user_last_login_null.py
0006_require_contenttypes_0002.py
0007_alter_validators_add_error_messages.py
0008_alter_user_username_max_length.py
0009_alter_user_last_name_max_length.py
__init__.py
__pycache__/
Kurts-MacBook-Pro:auth kurtpeek$ pwd
/Users/kurtpeek/.local/share/virtualenvs/lucy-web-oCa8O1zi/lib/python3.7/site-packages/django/contrib/auth
The problem is, I haven't checked the virtual env into version control, and I don't have access to the other computer at the moment. I also feel like I shouldn't have to check in the Django source code for the project, though.
My question is: how did this situation likely come to pass? What I suspect is that it is associated with the way the django.contrib.auth.User
model is customized in the project. We have a lucy_web/models/user.py
with content similar to the following:
from django.contrib.auth.models import User
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from django.db.models.signals import pre_save, post_save
from django.dispatch import receiver
from auditlog.registry import auditlog
from lucy_web.models import LucyGuide
from crequest.middleware import CrequestMiddleware
from lucy_web.lib import intercom
# overrides built in user to provide reasonable unique constraints
User._meta.get_field('username')._unique = True
# TODO(kayla): fix this, the unique constraint on email doesn't seem to be working in prod
# I suspect the username unique constraint only works because it's the default setting
User._meta.get_field('email')._unique = True
auditlog.register(User)
@property
def family(self):
if hasattr(self, 'employee_family'):
return self.employee_family
elif hasattr(self, 'partner_family'):
return self.partner_family
else:
return None
@property
def is_employee(self):
return hasattr(self, 'employee_family')
@property
def user_apn(self):
return self.userapn_set.order_by("created_at").last()
@property
def lucy_guide(self):
try:
return self.lucyguide
except LucyGuide.DoesNotExist:
return None
def user__str__(self):
"""
User model's __str__ method.
We use a different name than '__str__' because dunder names
are reserved by Python and subject to breakage without warning
(cf. https://www.python.org/dev/peps/pep-0562/#backwards-compatibility-and-impact-on-performance).
"""
return f"{self.first_name} {self.last_name}".strip()
@property
def profile(self):
if hasattr(self, 'user_profile'):
return self.user_profile
else:
return None
@property
def using_app(self):
if hasattr(self, 'user_profile'):
return self.user_profile.using_app
return False
@property
def activation_code(self):
if hasattr(self, 'user_profile'):
return self.user_profile.activation_code
return False
User.add_to_class('family', family)
User.add_to_class('is_employee', is_employee)
User.add_to_class('user_apn', user_apn)
User.add_to_class('lucy_guide', lucy_guide)
User.add_to_class('__str__', user__str__)
User.add_to_class('profile', profile)
User.add_to_class('using_app', using_app)
In short, we use the add_to_class
method to add properties to Django's User
model. This does not seem to be one of the recommended methods described in https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#extending-user. Is this perhaps the source of the problem?