I'm having a weird problem where normally field_val
should be set to some particular value but is being set to "". When I debug in vscode and look into the value from the debugger, inspecting it (possibly triggering something), suddenly the variable becomes available. When I'm not debugging the value is empty string. I couldn't understand what's happening here. Is there some kind of lazy evaluation that I'm missing in django forms?
I'm trying to keep the submitted value in the datalist when the form submission fails. Trying to take that value from the self.instance
which is an instance of my django db model basically.
class DatalistFieldMixin:
def make_field_datalist(self, field_name, choices, choice_format=lambda c: c):
field_val = getattr(self.instance, field_name) or ""
# Create the datalist widget while setting the html "value" attribute.
# And set the widget as the form field.
if self.fields.get(field_name):
widget = DatalistWidget(
choices=[choice_format(c) for c in choices],
attrs={"value": field_val},
)
self.fields[field_name].widget = widget
class ObjectAdminForm(DatalistFieldMixin, forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.make_field_datalist(
field_name="broadsign_active_container_id",
choices=BroadsignContainer.objects.all(),
choice_format=lambda c: (
c.container_id,
" - ".join((str(c.container_id), c.container_name)),
),
)
I couldn't understand what's happening here, but in the end I am getting the field value from the self.data
and self.instance
combined.
Essentially this ensures that the html datalist input value is being filled when:
And or ""
part in getattr(self.instance, field_name) or ""
was necessary due to getattr(self.instance, field_name)
literally existing as equal to None
.
class DatalistFieldMixin:
def make_field_datalist(self, field_name, choices, choice_format=lambda c: c):
field_val = self.data.get(field_name, getattr(self.instance, field_name) or "")
# Create the datalist widget while setting the html "value" attribute.
# And set the widget as the form field.
if self.fields.get(field_name):
widget = DatalistWidget(
choices=[choice_format(c) for c in choices],
attrs={"value": field_val},
)
self.fields[field_name].widget = widget