Django Form - динамически переключать существование поля - PullRequest
0 голосов
/ 11 декабря 2018

Python 2.7.8 и Django == 1.4.2 (устаревшее приложение)

Несколько месяцев назад я столкнулся с запутанной проблемой при исследовании ошибки в проекте Django.Я полагаю, это связано с тем, как Django объединяет потоки, но это действительно сложно определить.Вот минимальный жизнеспособный пример для воспроизведения этой проблемы:

class FormA(Form):
    field_a = CharField()

    def __init__(self, *args, **kwargs):
        if kwargs['initial']['test']:
            self.base_fields['field_b'] = CharField()
        super(FormA, self).__init__(*args, **kwargs)

class ViewA(FormView):
    template_name = 'test'
    form_class = FormA

    def get_initial(self):
        initial = super(ViewA, self).get_initial()
        initial['test'] = self.request.GET.get('test')

При динамическом добавлении нового поля на основе параметра запроса, если выполняется запрос с параметром запроса test с оценкой Trueво-первых, field_b будет включено в FormA.Но я подозреваю, что для всех последовательных запросов (даже если test оценивается как False), FormA сохраняет field_b .

Исправление для этого - выскочить или удалить field_b из self.base_fields и затем оцените тестовую переменную.Это работает, но я не совсем уверен, зачем это нужно.

def __init__(self, *args, **kwargs):
    self.base_fields.pop('field_b', 0)
    if kwargs['initial']['test']:
        self.base_fields['field_b'] = CharField()
    super(FormA, self).__init__(*args, **kwargs)

Кажется, что диктат base_fields сохраняется в нескольких запросах.Таким образом, возникает следующее:

1) Почему диктант base_fields не инициализируется повторно при каждом запросе?

2) Есть ли лучшее решение для решения этой проблемы вместо выполнения pop /del на base_fields?

3) Если нет другого решения, приводит ли pop / del к состоянию гонки?Что если оба запроса будут сделаны одновременно - один запрос испортит base_fields для другого запроса?

1 Ответ

0 голосов
/ 11 декабря 2018

Как уже упоминалось здесь , вам не следует изменять base_fields экземпляра.

Решение :

class FormA(Form):
    field_a = CharField()

    def __init__(self, *args, **kwargs):

        # this will populate `self.fields`
        super(FormA, self).__init__(*args, **kwargs)

        if kwargs['initial']['test']:
            self.fields['field_b'] = CharField()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...