1

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:

widgets

modelforms

Thanks for your help and input.

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much. I actually tried and used a different method that seems to also work, although it's not as straight-forward as yours. like so mychoices_cb = forms.MultipleChoiceField(label='Checkbox For', required=False, widget = forms.CheckboxSelectMultiple, choices=CHOICES), problem is now, I don't know how to default them to all checked. I really wish Django documentation is a bit more helpful so that I don't have to do trial and errors on acceptable attributes. Do you know?
Found it. initial = (c[0] for c in CHOICES).
@mariodev I'm using your custom widget in combination with: stackoverflow.com/a/8152717/3849359. Therefore I had to change it a little, because my values are given back already as bitchoices, and I only need to sum them. Now I would like get the inverse, because I would like to edit the choice also. Could you please help? Here is my question: stackoverflow.com/q/25575951/3849359
-1

Try Select2. It's a much better option.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.