Skip to content

Commit ced4137

Browse files
committed
widget referencs
1 parent 97738e4 commit ced4137

25 files changed

+507
-59
lines changed

doc/source/reference/fields.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ Fields
99
.. note::
1010

1111
:class:`~django_enum.fields.EnumField` automatically determines the most appropriate database
12-
column type based on the :class:`~enum.Enum` subclass it is assigned to. It is not recommended to
13-
use the specialized field types listed here directly.
12+
column type based on the :class:`~enum.Enum` subclass it is assigned to.
1413

1514
.. automodule:: django_enum.fields
1615
:members:

doc/source/reference/forms.rst

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22

33
.. _forms_ref:
44

5-
=====
6-
Forms
7-
=====
8-
9-
Fields
10-
------
5+
===========
6+
Form Fields
7+
===========
118

129
.. autoclass:: django_enum.forms.ChoiceFieldMixin
1310
:members:
@@ -24,34 +21,3 @@ Fields
2421
.. autoclass:: django_enum.forms.EnumMultipleChoiceField
2522
:members:
2623
:show-inheritance:
27-
28-
Widgets
29-
-------
30-
31-
.. autoclass:: django_enum.forms.NonStrictSelect
32-
:members:
33-
:show-inheritance:
34-
35-
.. autoclass:: django_enum.forms.NonStrictSelectMultiple
36-
:members:
37-
:show-inheritance:
38-
39-
.. autoclass:: django_enum.forms.FlagSelectMultiple
40-
:members:
41-
:show-inheritance:
42-
43-
.. autoclass:: django_enum.forms.FlagCheckbox
44-
:members:
45-
:show-inheritance:
46-
47-
.. autoclass:: django_enum.forms.NonStrictFlagSelectMultiple
48-
:members:
49-
:show-inheritance:
50-
51-
.. autoclass:: django_enum.forms.NonStrictFlagCheckbox
52-
:members:
53-
:show-inheritance:
54-
55-
.. autoclass:: django_enum.forms.NonStrictRadioSelect
56-
:members:
57-
:show-inheritance:

doc/source/reference/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Reference
1818
choices
1919
filters
2020
forms
21+
widgets
2122
query
2223
DRF
2324
urls

doc/source/reference/widgets.rst

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.. include:: ../refs.rst
2+
3+
.. _widgets_ref:
4+
5+
=======
6+
Widgets
7+
=======
8+
9+
The widgets below provide example renderings using these enums:
10+
11+
.. _color_ex:
12+
.. literalinclude:: ../../../tests/examples/enums/color.py
13+
:lines: 5-
14+
15+
.. _permissions_ex:
16+
.. literalinclude:: ../../../tests/examples/enums/permissions.py
17+
:lines: 5-
18+
19+
20+
Django's builtin :class:`~django.forms.Select` widget is the default widget used for
21+
:class:`~django_enum.fields.EnumField` fields. It renders a simple drop down select box.
22+
For example:
23+
24+
.. code-block:: Python
25+
26+
class Model(models.Model):
27+
color = EnumField(Color, default=Color.RED)
28+
29+
Model.objects.create()
30+
31+
.. image:: ../widgets/Select.png
32+
:alt: Select widget
33+
34+
.. autoclass:: django_enum.forms.NonStrictSelect
35+
:members:
36+
:show-inheritance:
37+
38+
.. autoclass:: django_enum.forms.NonStrictSelectMultiple
39+
:members:
40+
:show-inheritance:
41+
42+
.. autoclass:: django_enum.forms.FlagSelectMultiple
43+
:members:
44+
:show-inheritance:
45+
46+
.. autoclass:: django_enum.forms.FlagCheckbox
47+
:members:
48+
:show-inheritance:
49+
50+
.. autoclass:: django_enum.forms.NonStrictFlagSelectMultiple
51+
:members:
52+
:show-inheritance:
53+
54+
.. autoclass:: django_enum.forms.NonStrictFlagCheckbox
55+
:members:
56+
:show-inheritance:
57+
58+
.. autoclass:: django_enum.forms.NonStrictRadioSelect
59+
:members:
60+
:show-inheritance:
61+
62+
63+
Mixins
64+
------
65+
66+
.. autoclass:: django_enum.forms.NonStrictMixin
67+
:members:
68+
69+
.. autoclass:: django_enum.forms.FlagMixin
70+
:members:
71+
72+
.. autoclass:: django_enum.forms.NonStrictFlagMixin
73+
:members:

doc/source/widgets/FlagCheckbox.png

4.1 KB
Loading
3.83 KB
Loading
4.33 KB
Loading
4.45 KB
Loading
Loading
4.77 KB
Loading
2.17 KB
Loading

doc/source/widgets/RadioSelect.png

3.54 KB
Loading
3.72 KB
Loading

doc/source/widgets/Select.png

1.79 KB
Loading

src/django_enum/forms.py

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
"EnumChoiceField",
4343
"EnumMultipleChoiceField",
4444
"EnumFlagField",
45+
"NonStrictMixin",
46+
"FlagMixin",
47+
"NonStrictFlagMixin",
4548
]
4649

4750

@@ -123,15 +126,42 @@ def render(self, *args, **kwargs):
123126

124127
class NonStrictSelect(NonStrictMixin, Select):
125128
"""
126-
This widget renders a select box that includes an option for each value on the
127-
enumeration.
129+
**This is the default widget used for** :class:`~django_enum.fields.EnumField`
130+
**fields that have** ``strict`` **set to** ``False``.
131+
132+
This widget will render a drop down select field that includes an option for each
133+
value on the enumeration, but if the field is set to a value outside of the
134+
enumeration it will be included and selected in the drop down:
135+
136+
For example, using our :ref:`Color <color_ex>` enumeration:
137+
138+
.. code-block:: python
139+
140+
class Model(models.Model):
141+
color = EnumField(Color, strict=False, max_length=12)
142+
143+
Model.objects.create(color="YELLOW")
144+
145+
.. image:: ../widgets/NonStrictSelect.png
128146
"""
129147

130148

131149
class NonStrictRadioSelect(NonStrictMixin, RadioSelect):
132150
"""
133-
This widget renders a radio select field that includes an option for each value on
134-
the enumeration and for any non-value that is set.
151+
This widget will render a radio button select field that includes an option for each
152+
value on the enumeration, but if the field is set to a value outside of the
153+
enumeration it will be included and selected:
154+
155+
For example, using our :ref:`Color <color_ex>` enumeration:
156+
157+
.. code-block:: python
158+
159+
class Model(models.Model):
160+
color = EnumField(Color, strict=False, max_length=12)
161+
162+
Model.objects.create(color="YELLOW")
163+
164+
.. image:: ../widgets/NonStrictRadioSelect.png
135165
"""
136166

137167

@@ -148,7 +178,7 @@ def __init__(self, enum: t.Optional[t.Type[Flag]] = None, **kwargs):
148178

149179
def format_value(self, value):
150180
"""
151-
Return a list of the flag's values.
181+
Return a list of the flag's values, unpacking it if necessary.
152182
"""
153183
if value is None:
154184
return []
@@ -174,15 +204,41 @@ def format_value(self, value):
174204

175205
class FlagSelectMultiple(FlagMixin, SelectMultiple):
176206
"""
207+
**This is the default widget used for** :class:`~django_enum.fields.FlagField`
208+
**fields.**
209+
177210
This widget will render :class:`~enum.IntFlag` types as a multi select field with
178-
an option for each flag value.
211+
an option for each flag value. Values outside of the enumeration will not be
212+
displayed.
213+
214+
For example, using our :ref:`Permissions <permissions_ex>` enumeration:
215+
216+
.. code-block:: python
217+
218+
class Model(models.Model):
219+
permissions = EnumField(Permissions)
220+
221+
Model.objects.create(permissions=Permissions.READ | Permissions.EXECUTE)
222+
223+
.. image:: ../widgets/FlagSelectMultiple.png
179224
"""
180225

181226

182227
class FlagCheckbox(FlagMixin, CheckboxSelectMultiple):
183228
"""
184229
This widget will render :class:`~enum.IntFlag` types as checkboxes with a checkbox
185230
for each flag value.
231+
232+
For example, using our :ref:`Permissions <permissions_ex>` enumeration:
233+
234+
.. code-block:: python
235+
236+
class Model(models.Model):
237+
permissions = EnumField(Permissions)
238+
239+
Model.objects.create(permissions=Permissions.READ | Permissions.EXECUTE)
240+
241+
.. image:: ../widgets/FlagCheckbox.png
186242
"""
187243

188244

@@ -201,6 +257,17 @@ class NonStrictFlagSelectMultiple(NonStrictFlagMixin, FlagSelectMultiple):
201257
202258
Options for extra bits only appear if they are set. You should pass choices to the
203259
form field if you want additional options to always appear.
260+
261+
.. code-block:: python
262+
263+
class Model(models.Model):
264+
permissions = EnumField(Permissions, strict=False)
265+
266+
Model.objects.create(
267+
permissions=Permissions.READ | Permissions.EXECUTE | ( 1 << 4 )
268+
)
269+
270+
.. image:: ../widgets/NonStrictFlagSelectMultiple.png
204271
"""
205272

206273

@@ -211,6 +278,19 @@ class NonStrictFlagCheckbox(NonStrictFlagMixin, FlagCheckbox):
211278
212279
Checkboxes for extra bits only appear if they are set. You should pass choices to
213280
the form field if you want additional checkboxes to always appear.
281+
282+
For example, using our :ref:`Permissions <permissions_ex>` enumeration:
283+
284+
.. code-block:: python
285+
286+
class Model(models.Model):
287+
permissions = EnumField(Permissions, strict=False)
288+
289+
Model.objects.create(
290+
permissions=Permissions.READ | Permissions.EXECUTE | ( 1 << 4 )
291+
)
292+
293+
.. image:: ../widgets/NonStrictFlagCheckbox.png
214294
"""
215295

216296

tests/examples/admin.py

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
import sys
22
from django.contrib import admin
3-
3+
from django.forms import ModelForm, Select, RadioSelect
4+
from django_enum.forms import (
5+
NonStrictRadioSelect,
6+
FlagSelectMultiple,
7+
FlagCheckbox,
8+
NonStrictFlagCheckbox,
9+
NonStrictFlagSelectMultiple,
10+
NonStrictSelect,
11+
NonStrictSelectMultiple
12+
)
413
from tests.examples.models import (
514
Map,
615
BasicExample,
@@ -9,7 +18,12 @@
918
StrictExample,
1019
PropertyExample,
1120
ChoicesWithProperties,
12-
TextChoicesExample
21+
TextChoicesExample,
22+
WidgetDemoStrict,
23+
WidgetDemoNonStrict,
24+
WidgetDemoRadiosAndChecks,
25+
WidgetDemoRadiosAndChecksNonStrict,
26+
WidgetDemoRadiosAndChecksNulls
1327
)
1428

1529
admin.site.register(Map)
@@ -20,3 +34,77 @@
2034
admin.site.register(FlagExample)
2135
admin.site.register(ChoicesWithProperties)
2236
admin.site.register(TextChoicesExample)
37+
38+
39+
class WidgetDemoStrictAdminForm(ModelForm):
40+
class Meta:
41+
model = WidgetDemoStrict
42+
fields = "__all__"
43+
widgets = {
44+
"color": Select,
45+
"permissions": FlagSelectMultiple,
46+
}
47+
48+
49+
class WidgetDemoStrictAdmin(admin.ModelAdmin):
50+
form = WidgetDemoStrictAdminForm
51+
52+
53+
admin.site.register(WidgetDemoStrict, WidgetDemoStrictAdmin)
54+
55+
56+
class WidgetDemoNonStrictAdminForm(ModelForm):
57+
class Meta:
58+
model = WidgetDemoNonStrict
59+
fields = "__all__"
60+
widgets = {
61+
"color": NonStrictSelect,
62+
"permissions": NonStrictFlagSelectMultiple,
63+
}
64+
65+
66+
class WidgetDemoNonStrictAdmin(admin.ModelAdmin):
67+
form = WidgetDemoNonStrictAdminForm
68+
69+
70+
71+
admin.site.register(WidgetDemoNonStrict, WidgetDemoNonStrictAdmin)
72+
73+
74+
class WidgetDemoRadiosAndChecksAdminForm(ModelForm):
75+
class Meta:
76+
model = WidgetDemoRadiosAndChecks
77+
fields = "__all__"
78+
widgets = {
79+
"color": RadioSelect,
80+
"permissions": FlagCheckbox,
81+
}
82+
83+
84+
class WidgetDemoRadiosAndChecksAdmin(admin.ModelAdmin):
85+
form = WidgetDemoRadiosAndChecksAdminForm
86+
87+
88+
class WidgetDemoRadiosAndChecksNullsAdmin(admin.ModelAdmin):
89+
form = WidgetDemoRadiosAndChecksAdminForm
90+
91+
92+
admin.site.register(WidgetDemoRadiosAndChecks, WidgetDemoRadiosAndChecksAdmin)
93+
admin.site.register(WidgetDemoRadiosAndChecksNulls, WidgetDemoRadiosAndChecksNullsAdmin)
94+
95+
96+
class WidgetDemoRadiosAndChecksNonStrictAdminForm(ModelForm):
97+
class Meta:
98+
model = WidgetDemoRadiosAndChecksNonStrict
99+
fields = "__all__"
100+
widgets = {
101+
"color": NonStrictRadioSelect,
102+
"permissions": NonStrictFlagCheckbox,
103+
}
104+
105+
106+
class WidgetDemoRadiosAndChecksNonStrictAdmin(admin.ModelAdmin):
107+
form = WidgetDemoRadiosAndChecksNonStrictAdminForm
108+
109+
110+
admin.site.register(WidgetDemoRadiosAndChecksNonStrict, WidgetDemoRadiosAndChecksNonStrictAdmin)

0 commit comments

Comments
 (0)