After doing some extensive changes in the DB schema, I ran makemigrations. It created migrations successfully. But then migrate failed with:
AttributeError: 'str' object has no attribute '_meta'
This is the code that I changed. I split up the Many to Many model for Hardskills from one through table to 2 different through table for users and jobs.
Initial
class Hardskills(models.Model):
user = models.ManyToManyField(User, related_name="user_hs",through="HardskillsProfile")
job = models.ManyToManyField(Job, related_name="job_hs",through="HardskillsProfile")
hardskills = models.CharField(max_length=100, db_index=True)
def __str__(self):
return self.hardskills
class HardskillsProfile(models.Model):
"""Through Model for Many to Many relationship for user/jobs and hardskills"""
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user",null=True)
job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name="job",null=True)
hardskills = models.ForeignKey(Hardskills, on_delete=models.CASCADE)
Final after changes
from attributes.models import Category
from django.contrib.auth.models import User
from content.models import Job
from django.db import models
class Hardskills(models.Model):
user = models.ManyToManyField(User, related_name="user_hs",through="UserHardskillsProfile")
job = models.ManyToManyField(Job, related_name="job_hs",through="JobHardskillsProfile")
hardskills = models.CharField(max_length=100, db_index=True)
def __str__(self):
return self.hardskills
class UserHardskillsProfile(models.Model):
"""Through Model for Many to Many relationship for user and hardskills"""
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user",null=True)
hardskills = models.ForeignKey(Hardskills, on_delete=models.CASCADE)
class JobHardskillsProfile(models.Model):
"""Through Model for Many to Many relationship for user/jobs and hardskills"""
job = models.ForeignKey(Job, on_delete=models.CASCADE, related_name="job",null=True)
hardskills = models.ForeignKey(Hardskills, on_delete=models.CASCADE)
Error Logs
Operations to perform:
Synchronize unmigrated apps: messages, rest_framework, staticfiles
Apply all migrations: accounts, admin, attributes, auth, authtoken, content, contenttypes, data, interactions, scoring, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying scoring.0017_auto_20201224_1023...Traceback (most recent call last):
File "manage.py", line 22, in <module>
main()
File "manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/core/management/base.py", line 330, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/core/management/base.py", line 371, in execute
output = self.handle(*args, **options)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/core/management/base.py", line 85, in wrapped
res = handle_func(*args, **kwargs)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 245, in handle
fake_initial=fake_initial,
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/migrations/executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/migrations/executor.py", line 227, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/migrations/migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/migrations/operations/fields.py", line 236, in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/backends/sqlite3/schema.py", line 138, in alter_field
super().alter_field(model, old_field, new_field, strict=strict)
File "/home/yk09/miniconda3/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 555, in alter_field
old_field.remote_field.through._meta.auto_created and
AttributeError: 'str' object has no attribute '_meta'
Can anyone kindly advise? If my question is not clear, please do let me know as well :)
In the migration file scoring.0017_auto_20201224_1023...
there will be list of operations. in that you can find a delete model migration.
move it to the end of migration list, like
From
[
...
migrations.DeleteModel(
name='HardskillsProfile',
),
migrations.AlterField(...),
...
]
To
[
...
migrations.DeleteModel(
name='HardskillsProfile',
],
then migrate.
Got this idea going through this ticket. which is supposably fixed, makemigrations is supposed to handle dangling reference which happens if a referenced model is deleted earlier in migration and referred later, so you can manually rearrange them.