Ticket #4136: 4136_NullableWidget.py

File 4136_NullableWidget.py, 2.0 KB (added by frostnzcr4, 3 years ago)

Working NullableWidget

Line 
1'''
2my_project/my_widgets.py
3
4'''
5from django.forms import CheckboxInput, MultiWidget
6
7
8class NullableWidget(MultiWidget):
9    """
10    A Widget that wraps another Widget and renders it along with a checkbox
11    that unchecked means that the value should be None (NULL) [#4136]
12
13    """
14    def __init__(self, subwidget, attrs=None):
15        self.checkbox = CheckboxInput()
16        self.subwidget = subwidget
17        super(NullableWidget, self).__init__(
18            [self.checkbox, self.subwidget], attrs
19        )
20
21    def decompress(self, value):
22        if value is None:
23            return [False, '']
24        else:
25            return [True, value]
26
27    def value_from_datadict(self, data, files, name):
28        is_set, value = [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
29
30        if is_set:
31            return value
32        else:
33            return None
34
35    def _has_changed(self, initial, data):
36        '''
37        When checkbox is unticked and Text
38        '''
39        if initial is None:
40            initial = self.decompress(initial)
41        else:
42            if not isinstance(initial, list):
43                initial = self.decompress(initial)
44
45        multi_data = self.decompress(data)
46        for widget, initial, data in zip(self.widgets, initial, multi_data):
47            if widget._has_changed(initial, data):
48                return True
49        return False
50
51'''
52my_project/models.py
53
54'''
55from django.db import models
56
57class MyModel(models.Model):
58    my_nullable_charfield = models.CharField("verbose name",
59        blank=True,
60        null=True,
61        unique=True,
62        default=None,
63        max_length=3)
64'''
65my_project/forms.py
66
67'''
68from django import forms
69
70from my_project.models import MyModel
71from my_project.my_widgets import NullableWidget
72
73
74class MyModelForm(forms.ModelForm):
75    class Meta:
76        model = MyModel
77        widgets = {
78            "my_nullable_charfield": NullableWidget(forms.TextInput())
79        }
Back to Top