Использование 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
Вернуться на верх