Использование Model.objects.filter в форме не позволяет мне обновлять модель
У меня есть форма, настроенная следующим образом: я использую значения из TestModel
для создания поля select в форме. Однако если я хочу обновить TestModel
, чтобы добавить новый столбец, Django выдает мне psycopg2.errors.UndefinedColumn
, говоря, что новый столбец не найден в таблице, и трассировка стека указывает на эту форму ModelChoiceField
. Только после того, как я закомментирую этот select, я смогу выполнить миграцию в базу данных.
Итак, мой вопрос: есть ли лучший способ настроить это ModelChoiceField
, где мне не нужно раскомментировать это, чтобы обновить базовую модель в базе данных? Я использую Django 4.0 и python 3.8 для справки.
class TestModelChoiceField(forms.ModelChoiceField):
"""
Overwriting model choice field attribute to use
a different __str__ representation than the default
model
"""
def label_from_instance(self, obj):
return obj.test_field
class TestForm(forms.Form):
first_select = TestModelChoiceField(
queryset=TestModel.objects.filter(model_attribute__isnull=False),
initial=TestModel.objects.filter(model_attribute__isnull=False)
.filter(test_field="Yes")
.first()
.team_id,
label="Field One:",
)
Когда возникает необходимость доступа к базе данных в подобной форме, лучше всего подождать, пока форма будет инициализирована, а не во время выполнения, как вы делаете здесь. При такой настройке, как у вас, при запуске приложения форма загрузится и сразу же попытается запросить базу данных. Если вы подождете, пока приложение создаст экземпляр формы, вы можете быть уверены, что база данных будет готова/доступна.
Так что в итоге вы получите что-то вроде:
class TestForm(forms.Form):
first_select = TestModelChoiceField(
queryset=TestModel.objects.none(),
label="Field One:",
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['first_select'].queryset = TestModel.objects.filter(model_attribute__isnull=False)
self.fields['first_select'].initial = TestModel.objects.filter(
model_attribute__isnull=False
).filter(test_field="Yes").first().team_id