Django: Динамическая форма некорректно обрабатывает логические входы
Вот небольшая форма, которую я имею и динамически строю:
class AddonForm(Form):
def __init__(self, addons, *args, **kwargs):
super().__init__(self, *args, **kwargs)
self.addons = {str(addon.pk): addon for addon in addons}
for pk, addon in self.addons.items():
self.fields[str(pk)] = BooleanField(required=False, label=f"{addon} (x{addon.price_multiplier})")
Вот как я его использую:
form = AddonForm(ItemAddonTemplate.objects.filter(item=item_template_id), request.POST)
if form.is_valid():
addons = form.cleaned_data
Это запрос.POST:
<QueryDict: {'csrfmiddlewaretoken': ['cJS1fhGY3WqIflynGbZIh9TiRj8F9HjgoLOUL6TwWY4j4cotALGHpFDyQwjLiLMW'], '3': ['on'], '32': ['on']}>
но когда я печатаю аддоны, то вижу следующее:
{'3': False, '30': False, '31': False, '32': False, '33': False, '34': False}
3 и 32 должны быть True.
Это Django 5.1 и Python 3.12.
Может быть, это лучше реализовать, используя formsets
вместо этого:
forms.py
class AddonForm(Form):
on = BooleanField(required=False)
def __init__(self, addons, *args, **kwargs):
"""
Use addons qs(as list) to add and set
properties to the form and form fields
"""
super().__init__(*args, **kwargs)
addon = addons.pop(0)
self.label = f"{addon} (x{addon.price_multiplier})"
self.identifier = addon.id
self.fields["on"].label = self.label
def clean(self):
"""
Change cleaned_data representation
substituting the field name for addon.id
"""
cleaned_data = super().clean()
cleaned_data[f"{self.identifier}"] = cleaned_data.pop("on")
return cleaned_data
views.py
def item_addons(request, item_template_id):
addons = ItemAddonTemplate.objects.filter(item=item_template_id)
AddonFormSet = formset_factory(AddonForm, extra=len(addons))
formset = AddonFormSet(form_kwargs={"addons": list(addons)})
if request.method == "POST":
formset = AddonFormSet(request.POST, form_kwargs={"addons": list(addons)})
if formset.is_valid():
for form in formset:
if form.cleaned_data:
print(form.cleaned_data)
return render(request, "item_addons.html", {"formset": formset})
Который "возвращается":
{'3': True}
{'32': True}