ModelForm in template with a grouped choice field - django

I have a grouped category field. The problem is that I've created a search form, but when I try presente the form to the user in the template, it goes wrong.
models.py
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)
category = models.CharField(max_length=20, choices=MEDIA_CHOICES, verbose_name=_(u'Category'))
forms.py (search)
class SearchingForm(forms.Form):
"Search Box"
search = forms.CharField(max_length=100, required=False, label=(_(u'Search')))
music_kind = forms.MultipleChoiceField(choices=MEDIA_CHOICES, required=False,
label=(_(u'Kind')),
widget=forms.CheckboxSelectMultiple(),
)
template.html
{{ form.search }}
{{ form.place_kind }}
I show the form to the user like this, the problem is when I rendered with a browser I have something like this (in each line, it has a checkbox):
(('vinyl', 'Vinyl'), ('cd', 'CD'))
(('vhs', 'VHS Tape'), ('dvd', 'DVD'))
Unknown
I have delete the 'widget=forms.CheckboxSelectMultiple()' attribute it goes right, but I don't have a checkboxes. So, How I can do it with checkbox fields?

I think you have a data type mismatch here. You're wanting to store multiple values in a single CharField. Sure, you could save a dictionary of key-value pairs in there, but then you'd have to parse it back out into selections, and that's a huge pain.
I would move your MEDIA_CHOICES to a database table, and then in your SearchingForm, you can do a CheckboxSelectMultiple, and the form will behave as expected.

I'm not sure, but I wonder if choice groups are only for select boxes (not checkboxes).

Related

Django retrieve key of group ChoiceField

retrieve key of group ChoiceField
MEDIA_CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)
class ressource(models.Model):
....
media = models.CharField(max_length=50, choices=MEDIA_CHOICES)
in field media i have vinyl or cd or vhs or dvd...but how retrieve audio,video, unknown ?
You should prove us more details. First of all choices should be iterable object (tuple for example as it's in your case), but your tuple is very complicated in your case (Django can not process this). You should pass something like this as a choices.
choices example (This is good tuple code)
CHOICES = (
('key', 'value') # key will be inserted in database (and validation purposes), and value is just for representation purposes.
)
LANGUAGES = (
('python', 'Python'),
('js', 'JS'),
('ruby', 'Ruby'),
)
Imagine that, you are trying to retrieving object from database.
class ressource(models.Model):
''' This is your model '''
media = models.CharField(max_length=50, choices=MEDIA_CHOICES)
res = ressource.objects.get(pk=1) # retrieve data from database.
print(res.media) # returns string object. you will read actual value of media field
''' But if you want to read all available choices on this field, Django provide as _meta api. You can use it very nice way '''
res = ressource.objects.get(pk=1)
fields = res._meta.fields # This will return tuple-like object.
for field in fields:
if field.name == 'media':
# you want to find "media" field
print(field.choices) # This will return all available choices on your media field
Hope, it helps you. Good luck.

Django choicefield choices not displaying

Im using a choicefield and setting 2 values - 'students', 'teachers',
but for some reason when the form displays it only shows 'teachers' and not 'students'.
class SignUpShortForm(SignUpForm):
role = forms.ChoiceField(
choices=[],
widget=forms.Select(attrs={'class':'form-control'}),
label='I am a...',
)
self.fields['role'].choices = [('Teacher', 'Teacher2')]
Please look here You add to your choices only values without keys. Code might look like this:
CHOICES = (
('students', 'Students'),
('teachers', 'Teachers'),
)
class SignUpShortForm(SignUpForm):
role = forms.ChoiceField(
choices=CHOICES,
widget=forms.Select(attrs={'class':'form-control'}),
label='I am a...',
)

How do I set a Many-to-Many relation for predefined chocies in Django models?

I have a WorderOrder class that has predefined work order types:
class WorkOrder( models.Model ) :
WORK_TYPE_CHOICES = (
( 'hc', 'Heating and cooling' ),
( 'el', 'Electrical' ),
( 'pl', 'Plumbing' ),
( 'ap', 'Appliances' ),
( 'pe', 'Pests' ),
( 'ex', 'Exterior' ),
( 'in', 'Interior' ),
( 'ot', 'Others' ),
)
work_type = models.CharField( max_length = 2, choices = WORK_TYPE_CHOICES )
vendor = models.ForeignKey( Vendor, null = True, blank = True )
Therefore each order must have one work order type. Later down the road, a vendor can also be assigned to a work order.
I want the Vendor class to have a M2M relationship to the same work order choices in the WorkOrder class. In other words, each vendor are able to do one or many work types. For example, Bob's Plumbing can only do "Plumbing", whereas Solid Home Repair can do "Electrical", "Plumbing", "Exterior", and "Interior".
I understand I can create another table called WorkType and use foreign keys from WorkOrder and a M2M from Vendor, but since I feel I won't be changing the work type choices, I would rather have them predefined in models.py.
Also if I can predefine it in models.py, then I don't have to pre-populate the table WorkType during deployments and upgrades.
Some options for you:
create a model for work_type_choices, instantiate the records (hc, el, etc), then use a manytomany field, or
create a charfield and save CSV values to it (eg: "hc, el"), spliting/joining the value into it's elements as required, or
encapsule the above charfield and functions into a custom field and use that
leverage someone else's snippet, eg:
http://djangosnippets.org/snippets/1200/

Django ChoicesField divider?

I'm using a ChoicesField in my form, but I want to put a divider in it like this:
COUNTRIES = (
('CA', _('Canada')),
('US', _('United States')),
(None, _('---')), # <----------
('AF', _('Afghanistan')),
('AX', _('Aland Islands')),
('AL', _('Albania')),
('DZ', _('Algeria')),
('AS', _('American Samoa')),
# ...
class AddressForm(forms.Form):
country = forms.ChoiceField(choices=COUNTRIES, initial='CA')
What's the easiest way to make that unselectable, or at least give an error if the user picks it?
You can use this: https://docs.djangoproject.com/en/dev/ref/models/fields/#field-choices
You would format it like this:
COUNTRIES = [
("CA", _("Canada")),
("US", _("United States")),
# This format will indent the nested tuples over and the
# "-----" will be un-selectable
#
("---------------", ( # This will be a header for the items nested below
("AF", _("Afghanistan")),
('AX', _('Aland Islands')),
('AL', _('Albania')),
('DZ', _('Algeria')),
('AS', _('American Samoa')),
)
),
]
You could write a clean method to raise a validation error if any divider is selected.
class AddressForm(forms.Form):
country = forms.ChoiceField(choices=COUNTRIES, initial='CA')
def clean_country(self):
data = self.cleaned_data["country"]
if not data:
raise forms.ValidationError("You must select a valid country.")
return data
I don't know what version of Django you are using, but I am on 1.10.1 and I used the following:
ICONS = (
(None, ''),
(None, '==Extra Contact Info=='),
('phone', 'Phone'),
('phone', 'Phone (square)'),
('fax', 'Fax'),
('envelope', 'E-mail (black)'),
('envelope-o', 'E-mail (white/clear)'),
(None, ''),
(None, '==Social Media=='),
('facebook', 'Facebook'),
('facebook-official', 'Facebook (official)'),
('facebook-square', 'Facebook (square)'),
('google-plus', 'Google Plus'),
...
)
and that's all I used, and if a user selects any list item in a drop-down menu that has a 'None' value in it, it will bark at the user saying "This field is required."
Now... of course in my project, the choices list is being used in my whatever.com/admin page, but that may not be relevant. What is relevant however, is that you have to ensure your model (or form) class field does not contain "blank = True". By default it should be false if you omit it, in other words the field won't accept null or empty string values. That should be all you need...

form with CheckboxSelectMultiple doesn't validate

I have a form with a choice field that is using CheckboxSelectMultiple widget:
foo = forms.ChoiceField(widget=forms.CheckboxSelectMultiple,
choices=(
("1", "ONE"),
("2", "TWO"),
))
The form renders fine showing two checkboxes, however it doesn't validate.
If I select both checkboxes I am getting an error: Select a valid choice. [u'1', u'2'] is not one of the available choices
Selecting one checkbox doesn't work either, it gives me: Select a valid choice. [u'1'] is not one of the available choices.
What's going on here?
If you make the field a forms.MultipleChoiceField rather than a forms.ChoiceField it will work better.
May this helpful for you
num_choices = ( ("1", "ONE"), ("2", "TWO"), ("3", "Three"), ("4", "Four"))
num_list = forms.MultipleChoiceField(choices=num_choices, required=True, widget=forms.CheckboxSelectMultiple(), label='Select No', initial=("1", "2"))
If you want to pass the ORM object directly, then you can try the following
num_list = forms.ModelMultipleChoiceField(Numbers.objects.all(), required=True, widget=forms.CheckboxSelectMultiple(), label='Select No')