Django order choice field
Asked Answered
K

1

7

I've been struggling with Django choice fields in form. I have choices in my forms.py and a radio choice field.

DURATION_CHOICES = {
    (1, '30'),
    (2, '45'),
    (3, '60'),
    (4, '75'),
    (5, '90'),
    (6, '105'),
    (7, '120+'),
}

duration = forms.ChoiceField(choices=DURATION_CHOICES, widget=forms.widgets.RadioSelect, label_suffix="", label="Trainingsdauer in Minuten",)

However when I open the form to create a new training session, the duration radio select field is randomly ordered, i.e. 105 is in the list before 45. The order even changes from testing devices to another

I have the very same problem with choice fields from models.py

I have already ordered my choices but how do I get the ordered choice list in my form?

Kiley answered 21/5, 2018 at 13:33 Comment(1)
You here defined a set ot a list.Rubescent
R
9

I think this is more a problem with the collection you use. You here use curly quotes ({}). This is a set. A set us an unordered collection of hashable elements that occur zero or one time. But as said, the collection is unordered. This means there are no guarantees if you enumerate over the collection in what order you will retrieve it.

Use a list or tuple

I think you better use a list or a tuple here, which is an ordered collection of elements. For lists you can use square brackets ([]), for tuples one uses round brackets (()):

DURATION_CHOICES = [
    (1, '30'),
    (2, '45'),
    (3, '60'),
    (4, '75'),
    (5, '90'),
    (6, '105'),
    (7, '120+'),
]

Sort the collection before you pass it as an argument

If you want to keep using the set, we can convert it to a list before adding it to the field. We can for instance use sorted(..) to sort it based on the first item of the tuple:

from operator import itemgetter

duration = forms.ChoiceField(
    choices=sorted(DURATION_CHOICES, key=itemgetter(0)),
    widget=forms.widgets.RadioSelect,
    label="Trainingsdauer in Minuten",
)

Note however that if you make changes to the DURATION_CHOICES set, those changes will not reflect in the ChoiceField, since we here made a shallow copy to a list.

Rubescent answered 21/5, 2018 at 13:53 Comment(3)
@EminBuğraSaral: there is a difference between a dictionary and a set. #34371099 A comma-separated list of items between curly braces is a set, if the items have however two expressions separated by a colon, then it is a dictionary.Rubescent
I didn't pay enough attention. Excuse my edit please.Theotokos
Thank you @WillemVanOnsem I definitely didn't pay enough attention on the collection type. Really appreciate your explanationPreheat

© 2022 - 2024 — McMap. All rights reserved.