Django ModelForm Hidden Field to 'True' только в определенной ситуации?
У меня есть следующая Django Form; в ней есть поле под названием 'finished', которое скрыто. Я установил значение по умолчанию False, потому что есть только одна ситуация, когда я хочу, чтобы оно было установлено в True.
Проблема в том, что он по-прежнему отмечает его как "False", и я не могу понять, как изменить его в этой единственной ситуации.
У меня views.py
есть следующее:
context["test_form"] = TestForm(
instance=self.object, hide_status=True, is_finished=True
)
form
выглядит следующим образом:
class TestForm(ModelForm):
finished = forms.BooleanField(
widget=forms.HiddenInput(), initial=False, required=False
)
status = forms.Select(attrs={"class": "form-control"})
def __init__(self, *args, **kwargs):
hide_status = kwargs.pop("hide_status", None)
is_finished = kwargs.pop("is_finished", None)
super().__init__(*args, **kwargs)
self.fields["status"].queryset = Status.objects.filter(active=True)
self.fields["status"].widget.attrs["class"] = "form-control"
if hide_status:
self.fields["status"].widget = HiddenInput()
if is_finished:
self.fields["finished"].initial = True
class Meta:
model = Test
fields = ["finished", "status"]
HTML очень прост:
<form method="post" action="{% url 'my_app:test-update' %}">
{% csrf_token %}
{{ test_form.as_p }}
<button type="submit" class="btn btn-primary">Finish</button>
</form>
Отрисованный HTML выглядит следующим образом:
<input type="hidden" name="finished" value="False" id="id_finished">
Какой лучший способ установить значение True в этом случае?
Вы можете попробовать установить значение скрытого поля непосредственно в шаблоне перед рендерингом формы. Это можно сделать с помощью атрибута attrs в forms.BooleanField, чтобы установить пользовательское значение для атрибута value.
В классе TestForm вы можете обновить поле finished, чтобы включить в него атрибут attrs:
finished = forms.BooleanField(
widget=forms.HiddenInput(), initial=False, required=False, attrs={'value': 'False'}
)
Затем в представлении вы можете обновить значение атрибута на основе переменной is_finished:
context["test_form"] = TestForm(
instance=self.object, hide_status=True, is_finished=True
)
if context["test_form"].is_valid(): context["test_form"].fields['finished'].widget.attrs['value'] = 'True' Наконец, в шаблоне вы можете отобразить форму как обычно:
<form method="post" action="{% url 'my_app:test-update' %}">
{% csrf_token %}
{{ test_form.as_p }}
<button type="submit" class="btn btn-primary">Finish</button>
</form>
Таким образом, когда форма отображается, скрытое поле будет иметь правильное значение, а когда форма отправляется, оно также будет иметь правильное значение.
РЕДАКТИРОВАНИЕ:
Да, можно обработать случай начального значения поля 'finished' в методе init формы.
Вы можете добавить параметр, такой как is_finished в конструктор формы и использовать его для установки начального значения поля 'finished'. Например:
class TestForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
is_finished = kwargs.pop('is_finished', False)
super().__init__(*args, **kwargs)
self.fields['finished'].initial = is_finished
...
Затем в представлении вы можете использовать переменную is_finished для передачи форме
form = TestForm(request.POST, instance=test, is_finished=True)
Вы также можете использовать тот же подход в методе form_valid() UpdateView, как вы сделали, но, вероятно, лучше установить начальное значение в методе init так, чтобы это делалось при первом создании формы, а не при каждом действии формы.