ValueError: Related model u'app.model' cannot be resolved - django

I have two applications (ook and eek say) and I want to use a foreign key to a model in ook from a model in eek. Both are in INSTALLED_APPS with ook first.
In ook.models.py, i have:
class Fubar(models.Model):
...
In eek.models.py, I have:
class monkey(models.Model):
external = models.ForeignKey('ook.Fubar', blank=True, null=True)
...
The migration generated is:
class Migration(migrations.Migration):
dependencies = [
('eek', '0002_auto_20151029_1040'),
]
operations = [
migrations.AlterField(
model_name='monkey',
name='external',
field=models.ForeignKey(blank=True, to='ook.Fubar', null=True),
),
]
When I run the migration, I get this error:
...
1595 raise ValueError('Foreign Object from and to fields must be
the same non-zero length')
1596 if isinstance(self.rel.to, six.string_types):
-> 1597 raise ValueError('Related model %r cannot be resolved' % self.rel.to)
1598 related_fields = []
1599 for index in range(len(self.from_fields)):
ValueError: Related model u'ook.Fubar' cannot be resolved
What am I doing wrong?

Because You have ForeignKey in operations, You must add a ook to dependencies:
dependencies = [
('ook', '__first__'),
('eek', '0002_auto_20151029_1040'),
]
Django migrations have two "magic" values:
__first__ - get module first migration
__latest__ - get module latest migration

Try running migrations one by one for every model.
This way you can debug the app you are facing problem with
python manage.py migrate appmname

I just got the same error, but referring to a model that was declared as part of the same migration. It turned out that the first migrations.CreateModel(...) referred to a not yet declared model. I manually moved this below the declaration of the referred model and then everything worked fine.

In my case, It was the cache and previous migrations that resulted in this error. I removed __pycache__ and migrations folder and then re-run the migrations command and it worked.
Remember, when you'll do python manage.py makemigrations it won't see any new migrations and will console output no changes detected. You'll have to do python manage.py makemigrations your_app_name instead to make things work.

I encountered this error when trying to use a child model of a base model as a foreign key. It makes sense that it didn't work because there's not an id field on the child model. My fix was to use the parent on the key. Unfortunately this was not immediately intuitive and set me back a couple hours.

I have found that it looks like this bug was not fixed yet when you scroll down to the bottom.
Django ValueError: Related model cannot be resolved Bug
I am using 1.11.7, they are talking about 1.9.3.
It worked everything on localhost, but was always failing on Heroku, so I tested all the options/answers above and nothing worked.
Then I have noticed, localhost DB in Admin I had 1 profile created (1 DB record), went to Heroku and DB has 0 records for Profile table so I have added 1, pushed the migration, python manage.py migrate and all it went OK.
That validates that I did not need to change any of those migrations manually that all is working.
Maybe it will help to someone.
migrations
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-11-23 21:26
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('blog', '0005_blog_author'),
]
operations = [
migrations.AlterField(
model_name='blog',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
to='core.Profile'),
),
]

order of dependencies is too important.
in your case, ook must be created first then depend eek on it.
dependencies= [
('ook', '0001_initial'),
('eek', '0002_auto_20151029_1040'),
]

Related

Django database migration not working, new table not created

I initially created a database in mysql and used inspectdb to create all the models. So far so good, but then I started trying to make changes to the models and migrating them. I added columns to no avail, there were no changes in the database even though the migrations folder showed the changes. I began to wonder if it was something to do with case, so I tried again with a second model TestTwoT with table name and all fields in lower case. I then ran the make migrations which produced this output:
Migrations for 'testdb':
testdb/migrations/0010_testtwot.py
- Create model TestTwoT
The generated .py file in the migrations folder (which looks fine to me):
# Generated by Django 3.0.1 on 2020-02-10 22:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('testdb', '0009_auto_20200210_2241'),
]
operations = [
migrations.CreateModel(
name='TestTwoT',
fields=[
('id', models.AutoField(db_column='id', primary_key=True, serialize=False)),
('name', models.CharField(blank=True, db_column='name', max_length=1000, null=True)),
],
options={
'db_table': 'test_two_t',
'managed': True,
},
),
]
I then ran the migrate script which produced this output suggesting there were no problems creating the table:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, testdb, sessions
Running migrations:
Applying testdb.0010_testtwot... OK
However, still no sign of my new table when I run the 'show tables' sql command or the 'describe test_two_t' command.
There is another complication in my scenario in that I am not using the default database, but my setup seems entirely OK and my application is working fine pointing to the database.
EDIT : Following Borut's advice I changed the commands to (adding the --database parameter):
python3 manage.py makemigrations
python3 manage.py migrate --database=testdb
EDIT2 : It's all working perfectly now (after I also deleted all the previous migration .py files and started from scratch with the corrected above commands).
Following Borut's advice I changed the commands to (adding the --database parameter):
python3 manage.py makemigrations
python3 manage.py migrate --database=testdb
It's all working perfectly now (after I also deleted all the previous migration .py files and started from scratch with the corrected above commands).

django: adding custom permissions stopped working

I have a django project with multiple apps. In one of the apps when I add custom permissions to any model and run makemigration, the migration-file to add the permission is created. When I apply the migration I get no error messages but the permission isn't added to the auth_permission table.
class Meta:
app_label = 'my_app'
permissions = (
('assign_work_type', 'Assign work type'),
)
The migration completes without errors
I have tried doing the same in other apps and that works. I have also tried adding a column to the current app and that works as well. Anyone got any idea what it could be? I am running django 1.11.26
UPDATE
Here is the content of the migration file
# -*- coding: utf-8 -*-
# Generated by Django 1.11.26 on 2019-11-25 11:13
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('timereport', '0143_auto_20191122_1754'),
]
operations = [
migrations.AlterModelOptions(
name='worktype',
options={'permissions': (('assign_work_type', 'Assign work type'),)},
),
]
After quite some investigation I found that the affected app was missing the models_module, i.e. the "models.py" file. I have all my models in a /model/ directory and a while back I deleted the models.py file thinking it was of no use.
Adding the models.py file back solved the issue

Django finding non-existent changes to a model after each migration

After running python manage.py migrate, Django will consistently return:
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
Hmm that's funny, I don't remember making a change.
python manage.py makemigrations --dry-run --verbosity=3
Generated by Django 1.11 on 2017-0x-xx xx:xx
from __future__ import unicode_literals
from django.db import migrations, models
import django_cryptography.fields
class Migration(migrations.Migration):
dependencies = [
('myApp', '0019_auto_xxxxxxx_xx'),
]
operations = [
migrations.AlterField(
model_name='myModel',
name='encrypted_field',
field=django_cryptography.fields.encrypt(models.CharField(verbose_name=models.CharField(verbose_name=models.CharField(max_length=50, verbose_name='Encrypted Field')))),
),
migrations.AlterField(
model_name='myModel',
name='second_encrypted_field',
field=django_cryptography.fields.encrypt(models.CharField(verbose_name=models.CharField(verbose_name=models.CharField(max_length=50, verbose_name='Second encrypted field')))),
),
]
That would be fine, but the exact same AlterField() was run in 0018_auto. I've tested it out on a couple systems, even tried making these migrations for real and applying but, but the warning keeps coming back in 0020_auto.
myModel.__str__ does reference one of those encrypted fields, which I think is what's causing the recursion in the migration. Still, I can't understand why that would make Django keep picking them up.
Any idea what could be causing this? Is it a bug? Something having to do with the nature of django_cryptography? Something else?

right way to create a django data migration that creates a group?

I would like to create data migrations that create Permissions and Groups, so that my other developers can just run the migrations and get everything set up. I was able to create the migrations and run them just fine, but now I'm getting an error when running my tests.
But if I do this:
from django.contrib.auth.models import Group
def add_operations_group(apps, schema_editor):
Group.objects.get_or_create(name='operations')
I get:
django.db.utils.OperationalError: no such table: auth_group
If I do this:
def add_operations_group(apps, schema_editor):
Group = apps.get_model("django.contrib.auth", "group")
Group.objects.get_or_create(name='operations')
I get:
LookupError: No installed app with label 'django.contrib.auth'
Is there a way to do this? Or is there a "Django Way" to make sure things like permissions and groups are created?
This is how I do it:
from django.db import models, migrations
def apply_migration(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
Group.objects.bulk_create([
Group(name=u'group1'),
Group(name=u'group2'),
Group(name=u'group3'),
])
def revert_migration(apps, schema_editor):
Group = apps.get_model('auth', 'Group')
Group.objects.filter(
name__in=[
u'group1',
u'group2',
u'group3',
]
).delete()
class Migration(migrations.Migration):
dependencies = [
('someapp', 'XXXX_some_migration'),
]
operations = [
migrations.RunPython(apply_migration, revert_migration)
]
Although, there must be a more Djangonic way.
Answer from César is correct. To make it more Django create the migration file automatically by going to your django app root folder and entering:
python manage.py makemigrations <yourappname> --empty
Note: You may need python3 instead of python depending on your system configuration.
This creates an empty migration file in a sub directory of your app called 0001_initial.py
You can then alter it as per César instructions. Which worked correctly with Django 2.2

Django-migrations in Django 1.7 detects model changes but does not apply them on migrate

I have been trying to synchronize changes to a model in a Django app using migrations in 1.7 (postgres 9.1 - let me know if you need more details of my environment), but manage.py migrate doesn't seem to do anything, and sqlmigrate doesn't emit any SQL.
I thought Django 1.7 - "No migrations to apply" when run migrate after makemigrations might be applicable to my situation, and I did find some history in the django_migrations table in my database. I deleted the records for the app I am trying to migrate.
Recently I gave up on getting the alter table statements to generate/run and dropped the original version of the table. And while manage.py migrate states it is applying the migration, nothing happens to the database.
Here are the steps I've been trying:
Delete the history.
rm -r myapp/migrations
../manage.py dbshell
myapp_db=> delete from django_migrations where app='myapp'
Create an initial migration.
cp myapp/models.py.orig myapp/models.py
../manage.py makemigrations myapp
../manage.py migrate
manage.py migrate returns the following:
....
Running migrations:
Applying myapp.0001_initial... FAKED
Then I swap in the new models and generate a new migration.
cp myapp/models.py.new myapp/models.py
../manage.py makemigrations myapp
The result of makemigrations is in myapp/migrations/0002_notificationlog.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='NotificationLog',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('tstamp', models.DateTimeField(help_text=b'Log time', auto_now_add=True)),
('recipient', models.CharField(max_length=100)),
('subject', models.TextField()),
],
options={
},
bases=(models.Model,),
),
]
Run this migration:
../manage.py migrate
manage.py migrate acts like everything is OK:
....
Running migrations:
Applying myapp.0002_notificationlog... OK
I can see the log entries appear in django_migrations, but the table is not created.
I'm lost. Any idea what to try next?
Update
When running migrate -v 3 as requested, I see
Running pre-migrate handlers for application auth
followed by a similar line for each installed app.
Then
Loading 'initial_data' fixtures...
Checking '/var/www/environment/default/myproj/myproj' for fixtures...
No fixture 'initial_data' in '/var/www/environment/default/myproj/myproj'.
repeated a total of 13 times, the number of unmanaged apps.
Then
Running migrations:
Applying myapp.0001_initial... FAKED
followed by
Running post-migrate handlers for application auth
with a similar line for each installed app.
For migration 0002, the output is the same, except for
Running migrations:
Applying myapp.0002_notificationlog... OK
Note also that sqlmigrate doesn't output anything either:
../manage.py sqlmigrate myapp 0002 -v 3
Produces nothing at all.
Update 2
I copied myapp into a new project and was able to run migrations on it, but migrations stopped working when I imported my main project settings. Are there settings I should be aware of that could affect migration execution, particularly if I've been using South with previous versions of Django?
The problem disappeared with generic project settings and reappeared with my old, complex project settings. I tracked the problem down to a database Router class that was missing an allow_migrate method.
DATABASE_ROUTERS = [ 'myproj.routers.DatabaseAppsRouter', ]
I use this router to handle queries for a separate app in the project (readonly/MySQL).
Sadly I can't blame anyone but myself, since the Django documentation states clearly:
Note that migrations will just silently not perform any operations on a model for which [allow_migrate] returns False. (link)
I had created this router some time ago and didn't add the allow_migrate method to my router class when I upgraded to Django 1.7. When I added the method and made sure it returned True when needed, migrations run and the problem is solved.