Source code for modelqueryform.widgets

from django.core.exceptions import ValidationError
from django.db.models.aggregates import Min, Max
from django.forms.fields import Field
from django.forms.widgets import MultiWidget, CheckboxInput, NumberInput
from django.utils.safestring import mark_safe

from .utils import traverse_related_to_field


[docs]class RangeWidget(MultiWidget): ''' Build a MultiWidget with 3 fields: TextInput with a "min" attribute TextInput with a "max" attribute Checkbox to include/exclude None values ''' allow_null = False def __init__(self, allow_null=False, attrs=None, mode=0): _widgets = ( NumberInput(attrs=attrs), NumberInput(attrs=attrs), ) if allow_null: self.allow_null = True _widgets += (CheckboxInput(),) super(RangeWidget, self).__init__(_widgets, attrs)
[docs] def decompress(self, value): if value: decompress_value = [value['min'], value['max']] if self.allow_null: decompress_value += [value['allow_empty']] return decompress_value return [None, None]
[docs] def value_from_datadict(self, data, files, name): value = {} try: if not data[name + "_0"] == '': value['min'] = data[name + "_0"] value['max'] = data[name + "_1"] try: if data[name + "_2"]: value['allow_empty'] = True except: value['allow_empty'] = False except: pass return value
[docs] def format_output(self, rendered_widgets): html = '%s %s' % (rendered_widgets[0], rendered_widgets[1]) if self.allow_null: html = '%s <br/> %s %s' % (html, 'Include Empty values', rendered_widgets[2]) return mark_safe(u'%s' % html)
[docs]class RangeField(Field): def __init__(self, model, field, *args, **kwargs): range_min = model.objects.all().aggregate(Min(field))[field + "__min"] range_max = model.objects.all().aggregate(Max(field))[field + "__max"] super(RangeField, self).__init__(*args, **kwargs) self.widget = RangeWidget(allow_null=traverse_related_to_field(field, model).null, attrs={'min': range_min, 'max': range_max})
[docs] def to_python(self, value): if not value: return [] try: value['min'] = int(value['min']) value['max'] = int(value['max']) except: try: value['min'] = float(value['min']) value['max'] = float(value['max']) except: raise ValidationError('Values in RangeField must be numeric') return value
[docs] def validate(self, value): if value: if value['min'] > value['max']: raise ValidationError('Min must be less than or equal to Max')