"""
Some utilities related to the forms.
"""
from copy import copy
from django.contrib import messages
from django.forms.utils import ErrorList
from pytoolbox import module
_all = module.All(globals())
[docs]def conditional_required(form, required_dict, data=None, cleanup=False):
"""
Toggle requirement of some fields based on a dictionary with 'field name' -> 'required boolean'.
"""
data = data or form.cleaned_data
for name, value in data.items():
required = required_dict.get(name, None)
if required and not value:
form._errors[name] = ErrorList(['This field is required.'])
if required is False and cleanup:
data[name] = None
return data
[docs]def get_instance(form, field_name, request, msg=None):
"""
Return the instance if the `form` is valid, or try to get it from database.
Return None if not found and add an error message if set.
"""
if form.is_valid():
return form.cleaned_data[field_name]
queryset = form.fields[field_name].queryset
try:
return queryset.get(pk=form.data[form.add_prefix(field_name)])
except (KeyError, queryset.model.DoesNotExist):
if msg:
messages.error(request, msg)
[docs]def set_disabled(form, field_name, value=False):
"""Toggle the disabled attribute of a form's field."""
if value:
form.fields[field_name].widget.attrs['disabled'] = True
else:
try:
del form.fields[field_name].widget.attrs['disabled']
except Exception:
pass
[docs]def validate_start_end(form, data=None, start_name='start_date', end_name='end_date'):
"""
Check that the field containing the value of the start field (time, ...) is not bigger (>) than
the stop.
"""
data = data or form.cleaned_data
start, end = data[start_name], data[end_name]
if start and end and start > end:
form._errors[end_name] = ErrorList([
f"The {start_name.replace('_', ' ')} cannot be before the {end_name.replace('_', ' ')}."
])
__all__ = _all.diff(globals())