迁移与 forms.py 冲突
Migration clashes with forms.py
由于 forms.py
,命令 python manage.py makemigrations
大部分时间都失败,其中在 class 定义级别引用了新模型或新字段。
所以我必须注释每个这样的定义,以便迁移操作。这是一项痛苦的任务。
我不明白为什么迁移过程会导入 forms.py
模块。我认为导入模型模块应该就足够了。
有没有办法避免这些错误?
感谢@alasdair,我理解了我的问题并找到了解决方法:我替换了 views.py
文件中的原始代码
from MyApp import forms
与
import sys
if 'makemigrations' not in sys.argv and 'migrate' not in sys.argv:
from MyApp import forms
在我的情况下它工作正常,但我想有更好的方法来了解当前进程是否是迁移。如有请指教
通过可调用初始化...
def get_provinces():
province_choices = []
for province in ProvinceCode.objects.filter(country_code_id=1).order_by('code'):
province_choices.append((province.code, province.code))
return province_choices
class MemberForm(forms.Form):
provinces = forms.ChoiceField(label='Provinces',
choices=get_provinces, required=True)
参考这里 -
我遇到了同样的问题并找到了具体问题。当调用 migrate 命令时,Django 的系统检查进入了我的 forms.py,然后当他们遇到一行代码对迁移应该创建的 table 进行查询时会失败.我有一个选择字段,它使用这样的数据库查询来实例化选择:
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
)
解决方案是从选项中删除查询(将其保留为 [('', '')],然后改为在 class 的初始化方法中填充选项。
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()]
在您的查询中使用 .only 排除新列,如下所示:
University.objects.only('id', 'name').all()
然后运行你的迁移。
我的一个表单中的 ModelChoiceField
也遇到了类似的问题。我必须注释掉我的表单代码才能进行迁移。
对我来说,解决方案是将所有表单导入移动到 views.py
中各自的视图方法中。
之前:
from .forms import CalculatorForm
def calculator(request):
if request.method != 'POST':
form = CalculatorForm()
# ...
之后:
def calculator(request):
from .forms import CalculatorForm
if request.method != 'POST':
form = CalculatorForm()
# ...
自从 Django>=3.0 以来,一些管理命令可以在不使用检查框架的情况下通过来自 @erik-kalkoken 的 --skip-checks
(reference). So migrations could be applied, even if some code paths in forms, views, whatever are currently not in an ideal condition (again: see 提前调用以获得更清洁的解决方案):
./manage.py migrate --skip-checks
由于 forms.py
,命令 python manage.py makemigrations
大部分时间都失败,其中在 class 定义级别引用了新模型或新字段。
所以我必须注释每个这样的定义,以便迁移操作。这是一项痛苦的任务。
我不明白为什么迁移过程会导入 forms.py
模块。我认为导入模型模块应该就足够了。
有没有办法避免这些错误?
感谢@alasdair,我理解了我的问题并找到了解决方法:我替换了 views.py
文件中的原始代码
from MyApp import forms
与
import sys
if 'makemigrations' not in sys.argv and 'migrate' not in sys.argv:
from MyApp import forms
在我的情况下它工作正常,但我想有更好的方法来了解当前进程是否是迁移。如有请指教
通过可调用初始化...
def get_provinces():
province_choices = []
for province in ProvinceCode.objects.filter(country_code_id=1).order_by('code'):
province_choices.append((province.code, province.code))
return province_choices
class MemberForm(forms.Form):
provinces = forms.ChoiceField(label='Provinces',
choices=get_provinces, required=True)
参考这里 -
我遇到了同样的问题并找到了具体问题。当调用 migrate 命令时,Django 的系统检查进入了我的 forms.py,然后当他们遇到一行代码对迁移应该创建的 table 进行查询时会失败.我有一个选择字段,它使用这样的数据库查询来实例化选择:
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
)
解决方案是从选项中删除查询(将其保留为 [('', '')],然后改为在 class 的初始化方法中填充选项。
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()]
在您的查询中使用 .only 排除新列,如下所示:
University.objects.only('id', 'name').all()
然后运行你的迁移。
我的一个表单中的 ModelChoiceField
也遇到了类似的问题。我必须注释掉我的表单代码才能进行迁移。
对我来说,解决方案是将所有表单导入移动到 views.py
中各自的视图方法中。
之前:
from .forms import CalculatorForm
def calculator(request):
if request.method != 'POST':
form = CalculatorForm()
# ...
之后:
def calculator(request):
from .forms import CalculatorForm
if request.method != 'POST':
form = CalculatorForm()
# ...
自从 Django>=3.0 以来,一些管理命令可以在不使用检查框架的情况下通过来自 @erik-kalkoken 的 --skip-checks
(reference). So migrations could be applied, even if some code paths in forms, views, whatever are currently not in an ideal condition (again: see
./manage.py migrate --skip-checks