【问题标题】:Django migrate AttributeError: 'str' object has no attribute '_meta'Django migrate AttributeError:'str'对象没有属性'_meta'
【发布时间】:2021-04-02 20:38:23
【问题描述】:

在对 DB 架构进行了一些广泛的更改之后,我运行了 makemigrations。它成功创建了迁移。但随后迁移失败:

AttributeError: 'str' object has no attribute '_meta'

这是我更改的代码。我将 Hardskills 的多对多模型从一个表拆分为两个不同的用户和作业表。

首字母

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)

修改后的最终结果

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)

错误日志

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'

谁能给点建议?如果我的问题不清楚,也请告诉我:)

【问题讨论】:

    标签: python django sqlite django-models backend


    【解决方案1】:

    在迁移文件scoring.0017_auto_20201224_1023... 中会有操作列表。在那里你可以找到一个删除模型迁移。

    将其移至迁移列表的末尾,例如

    来自

        [
        ...    
        migrations.DeleteModel(
            name='HardskillsProfile',
        ),
        migrations.AlterField(...),
        ...
        ]
    

    收件人

        [
        ...
        migrations.DeleteModel(
            name='HardskillsProfile',
        ],
    

    然后迁移。

    通过this ticket 得到了这个想法。这可能是固定的,makemigrations 应该处理悬空引用,如果引用的模型在迁移早期被删除并稍后引用,则会发生这种情况,因此您可以手动重新排列它们。

    【讨论】:

    • 我可以知道这些行为的原因是什么吗?
    • 在 django 中找到了一个 ticket,它显示为已修复,从该线程中,我得到了手动重新排列迁移的提示,因为迁移生成器没有正确订购它们
    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多