1

Just wondering, I have the following model schema:

class Location(models.Model):

    SERVICE_CHOICES = (
        ('bus_station', 'Bus Station'),
        ('cafe', 'Café'),
        ('cinema', 'Cinema'),
        ('gardens', 'Public Gardens'),
        ('library', 'Library'),
        ('public_services', 'Public Services'),
        ('railway_station', 'Railway Station'),
        ('restaurant', 'Restaurant'),
        ('school', 'School'),
        ('shop', 'Shop'),
        ('supermarket', 'Supermarket'),
        ('tourist_attractions', 'Tourist Attractions'),
        ('transit_station', 'Transit Station'),
        ('walks', 'Walks'),
        ('woodland', 'Woodland'),
    )

    title = models.CharField("Title", max_length=60, default='')
    description = models.TextField("Description")
    service_type = models.CharField("Service Type", max_length=80, choices=SERVICE_CHOICES, default='public_service')

I'm just wondering how I would loop over the SERVICE_CHOICES tuple list on the frontend template?

{% for service_choice in location.SERVICE_CHOICES %}

?

On below suggestion, I have tried this in the view:

service_types = []

fields = Location._meta.fields()

for field in fields:
    if field.choices:
        service_types.append(field.choices)

2 Answers2

2
Location._meta.get_field('service_type').choices

you can simply do this

or

fields = Location._meta.fields()
for field in fields:
    if field.choices:
        print "%s: %s" % (field.name, field.choices)

or

Location.SERVICE_CHOICES 
Exprator
  • 26,992
  • 6
  • 47
  • 59
  • Yep - so these are used in the view. But then in the template I want to display the "pretty version"... –  Feb 11 '18 at 15:31
  • 1
    check the second option, send the field.choices to the template, and access field.choices – Exprator Feb 11 '18 at 15:32
  • Will do. Just crate an array and pass this to context I guess? –  Feb 11 '18 at 15:32
  • 1
    yup, take all the choices, put them in a list and pass it in the context to the template – Exprator Feb 11 '18 at 15:33
  • 'ImmutableList' object is not callable...? *I'm on Django 1.11 but more importantly maybe Python 3.6.1 –  Feb 11 '18 at 15:34
  • Added it to my question. –  Feb 11 '18 at 15:37
  • ohh yes, the things is that, the choices are of tuple, so you cannot add them, do try the first one i gave and check of else the last one to directly access them – Exprator Feb 11 '18 at 15:40
  • Doesn't seem to like `fields = Location._meta.fields()` < is there an error here? –  Feb 11 '18 at 15:40
  • Ok, yeh I started to do this and printed out the tuple. I will loop over these and append. –  Feb 11 '18 at 15:40
1

in your views.py

def view(request):
    ...
    choices = Location._meta.get_field('service_type').choices
    #or 
    choices = Location.SERVICE_CHOICES
    return render(request, 'template.html', { ... 'choices': choices})

You can also build a tag to get the list from the template (Django template tags docs):

templatetags/tags.py

from django import template

register = template.Library()

@register.assignment_tag
def get_choices(instance, field_name):
    return instance._meta.get_field(field_name).choices

template.html

{% get_choices instance 'service_type' as choices %}
{% for item in choices %}
     ...
{% endfor %}
Brian Ocampo
  • 1,345
  • 1
  • 12
  • 22