迁移与forms.py冲突

alb*_*bar 7 python django django-forms django-migrations

该命令python manage.py makemigrations大部分时间都会失败,因为forms.py在类定义级别引用了新模型或新字段.

因此,我必须对迁移的每个此类定义进行评论.这是一项痛苦的任务.

我不明白为什么迁移过程会导入forms.py模块.我认为导入模型模块应该足够了.

有没有办法避免这些错误?

Nat*_*ate 6

我遇到了同样的问题并找到了具体问题。当调用 migrate 命令时,Django 的系统检查进入我的 forms.py,然后当他们遇到一行代码对迁移应该创建的表进行查询时会失败。我有一个选择字段,它使用这样的数据库查询来实例化选择:

university = forms.ChoiceField(
    choices=[('', '')] + [(university.id, university.name) for university in University.objects.all()],
    widget=forms.Select(
        attrs={
            'class': 'form-control',
            'placeholder': 'University',
        }
    ),
    required=True
)
Run Code Online (Sandbox Code Playgroud)

解决方案是从选择中删除查询(将其保留为 [('', '')] ,然后在类的 init 方法中填充选择。

class UniversityForm(forms.Form):

    university = forms.ChoiceField(
        choices=[('', '')],
        widget=forms.Select(
            attrs={
                'class': 'form-control',
                'placeholder': 'University',
            }
        ),
        required=True
    )


def __init__(self, *args, **kwargs):
    super(UniversityForm, self).__init__(*args, **kwargs)

    # Load choices here so db calls are not made during migrations.
    self.fields['university'].choices = [('', '')] + [(university.name, university.name) for university in University.objects.all()]
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案!Django 导入 urls.py -> view.py -> forms.py,其中类声明执行类实例声明(如 `choices=...` 和 `querysets=`),因此后者必须移动到 `__init__ 中`。 (2认同)

alb*_*bar 3

感谢@alasdair,我理解了我的问题并找到了解决方法:我替换了文件中的原始views.py代码

from MyApp import forms
Run Code Online (Sandbox Code Playgroud)

import sys
if 'makemigrations' not in sys.argv and 'migrate' not in sys.argv:
    from MyApp import forms
Run Code Online (Sandbox Code Playgroud)

在我的情况下它工作得很好,但我认为有更好的方法来知道当前进程是否是迁移。如果是这样,请指教。

  • 这可能不是正确的方法。forms.py 中的问题应该得到修复 - 听起来它可能在导入时查询数据库,这不是一个好主意。请参阅 Nate 的答案,了解重组表单以避免这种情况的方法。 (3认同)