Reputation: 249
I have a model with an integer field and would like to have an alternative form input render other than the default textbox, so that I have the following:
models.py: myfield = models.IntegerField(default=7, blank=True)
Would like to have the following:
[x] Choice A (value 0)
[ ] Choice B (value 1)
[x] Choice C (value 2)
So that upon save
the choices would be calculated like the the following: (since choice A and C are selected and 2 is not selected).
myfield = sum(choice selected multiplied by the 2 to the value of the selected choice)
so that:
my field = (1 * 2^0) + (0 * 2^1) + (1 * 2^2)
my field = 1 + 0 + 4
my field = 5
#final value
If this was anything outside of Django, it would be more straight-forward via standard Checkbox grouping that does not map directly to a database field in the model, but with Django, i'm currently at a loss.
I have referenced the following materials, but still am unable to figure out what to do:
Thanks for your help and input.
Upvotes: 1
Views: 1995
Reputation: 15594
You can use custom widget like this:
from django import forms
class BinaryWidget(forms.CheckboxSelectMultiple):
def value_from_datadict(self, data, files, name):
value = super(BinaryWidget, self).value_from_datadict(data, files, name)
if name == 'myfield':
value = sum([2**(int(x)-1) for x in value])
return value
and override myfield
in your modelform as follows:
class MyModelForm(forms.ModelForm):
...
myfield = forms.IntegerField(widget=BinaryWidget(choices=(
('1', '2^0',), ('2', '2^1',), ('3', '2^2',)
)))
this will give you the expected result, although you probably will need a reverse feature - set initial values when editing for example, if so please let me know, so we can figure editing as well.
Upvotes: 4