290👍
In Django templates you can use the "get_FOO_display()
" method, that will return the readable alias for the field, where ‘FOO’ is the name of the field.
Note: in case the standard FormPreview
templates are not using it, then you can always provide your own templates for that form, which will contain something like {{ form.get_meal_display }}
.
68👍
The best solution for your problem is to use helper functions.
If the choices are stored in the variable CHOICES and the model field storing the selected choice is ‘choices‘ then you can directly use
{{ x.get_choices_display }}
in your template. Here, x is the model instance.
Hope it helps.
- [Django]-Are there any plans to officially support Django with IIS?
- [Django]-Celery discover tasks in files with other filenames
- [Django]-Paginate relationship in Django REST Framework?
53👍
My apologies if this answer is redundant with any listed above, but it appears this one hasn’t been offered yet, and it seems fairly clean. Here’s how I’ve solved this:
from django.db import models
class Scoop(models.Model):
FLAVOR_CHOICES = [
('c', 'Chocolate'),
('v', 'Vanilla'),
]
flavor = models.CharField(choices=FLAVOR_CHOICES)
def flavor_verbose(self):
return dict(Scoop.FLAVOR_CHOCIES)[self.flavor]
My view passes a Scoop to the template (note: not Scoop.values()), and the template contains:
{{ scoop.flavor_verbose }}
- [Django]-Can't install via pip because of egg_info error
- [Django]-How to define two fields "unique" as couple
- [Django]-Django migration strategy for renaming a model and relationship fields
11👍
Basing on Noah’s reply, here’s a version immune to fields without choices:
#annoyances/templatetags/data_verbose.py
from django import template
register = template.Library()
@register.filter
def data_verbose(boundField):
"""
Returns field's data or it's verbose version
for a field with choices defined.
Usage::
{% load data_verbose %}
{{form.some_field|data_verbose}}
"""
data = boundField.data
field = boundField.field
return hasattr(field, 'choices') and dict(field.choices).get(data,'') or data
I’m not sure wether it’s ok to use a filter for such purpose. If anybody has a better solution, I’ll be glad to see it 🙂 Thank you Noah!
- [Django]-Many-To-Many Fields View on Django Admin
- [Django]-How to pass multiple values for a single URL parameter?
- [Django]-Running a specific test case in Django when your app has a tests directory
7👍
We can extend the filter solution by Noah to be more universal in dealing with data and field types:
<table>
{% for item in query %}
<tr>
{% for field in fields %}
<td>{{item|human_readable:field}}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
Here’s the code:
#app_name/templatetags/custom_tags.py
def human_readable(value, arg):
if hasattr(value, 'get_' + str(arg) + '_display'):
return getattr(value, 'get_%s_display' % arg)()
elif hasattr(value, str(arg)):
if callable(getattr(value, str(arg))):
return getattr(value, arg)()
else:
return getattr(value, arg)
else:
try:
return value[arg]
except KeyError:
return settings.TEMPLATE_STRING_IF_INVALID
register.filter('human_readable', human_readable)
- [Django]-Chaining multiple filter() in Django, is this a bug?
- [Django]-Retrieving parameters from a URL
- [Django]-Update only specific fields in a models.Model
6👍
I don’t think there’s any built-in way to do that. A filter might do the trick, though:
@register.filter(name='display')
def display_value(bf):
"""Returns the display value of a BoundField"""
return dict(bf.field.choices).get(bf.data, '')
Then you can do:
{% for field in form %}
<tr>
<th>{{ field.label }}:</th>
<td>{{ field.data|display }}</td>
</tr>
{% endfor %}
- [Django]-How to use Django ImageField, and why use it at all?
- [Django]-Django Rest Framework File Upload
- [Django]-Running a specific test case in Django when your app has a tests directory
4👍
You have Model.get_FOO_display() where FOO is the name of the field that has choices.
In your template do this :
{{ scoop.get_flavor_display }}
- [Django]-Parsing unicode input using python json.loads
- [Django]-Is there a way to loop over two lists simultaneously in django?
- [Django]-What is the use of PYTHONUNBUFFERED in docker file?
3👍
Add to your models.py one simple function:
def get_display(key, list):
d = dict(list)
if key in d:
return d[key]
return None
Now, you can get verbose value of choice fields like that:
class MealOrder(models.Model):
meal = models.CharField(max_length=8, choices=CHOICES)
def meal_verbose(self):
return get_display(self.meal, CHOICES)
Upd.: I’m not sure, is that solution “pythonic” and “django-way” enough or not, but it works. 🙂
- [Django]-Split views.py in several files
- [Django]-Get class name of django model
- [Django]-How to resize an ImageField image before saving it in python Django model
0👍
The extended-extended version of Noah’s and Ivan’s solution. Also fixed Noah’s solution for Django 3.1, as ModelChoiceIteratorValue
is now unhashable.
@register.filter
def display_value(value: Any, arg: str = None) -> str:
"""Returns the display value of a BoundField or other form fields"""
if not arg: # attempt to auto-parse
# Returning regular field's value
if not hasattr(value.field, 'choices'): return value.value()
# Display select value for BoundField / Multiselect field
# This is used to get_..._display() for a read-only form-field
# which is not rendered as Input, but instead as text
return list(value.field.choices)[value.value()][1]
# usage: {{ field|display_value:<arg> }}
if hasattr(value, 'get_' + str(arg) + '_display'):
return getattr(value, 'get_%s_display' % arg)()
elif hasattr(value, str(arg)):
if callable(getattr(value, str(arg))):
return getattr(value, arg)()
return getattr(value, arg)
return value.get(arg) or ''
- [Django]-How can I get all the request headers in Django?
- [Django]-Multiple Database Config in Django 1.2
- [Django]-Differences between STATICFILES_DIR, STATIC_ROOT and MEDIA_ROOT
0👍
<select class="form-select">
{% for key, value in form.meal.field.choices %}
{% if form.meal.value == key %}
<option value="{{ form.key }}" selected>{{ value }}</option>
{% else %}
<option value="{{ key }}">{{ value }}</option>
{% endif %}
{% endfor %}
</select>
- [Django]-Django set default form values
- [Django]-Django – Annotate multiple fields from a Subquery
- [Django]-How to merge consecutive database migrations in django 1.9+?
0👍
Hey what about that way?
in models.py
class MealOrder(models.Model):
CHOICES = (
('s', 'Glorious spam'),
('e', 'Fabulous eggs'),
)
meal = models.CharField(max_length=8, choices=CHOICES)
meal_value = models.CharField(max_length=1, blank=True, null=True,
editable=False)
def save(self, *args, **kwargs):
if self.meal == "s":
self.meal_value = "Glorious spam"
elif self.meal == "e":
self.meal_value = "Fabulous eggs"
super(MealOrder, self).save(*args, **kwargs)
in views.py
from .models import MealOrder
def meal_order(request):
meals = MealOrder.objects.all()
return render(request, "meals.html", {
"meals": meals,
})
in meals.html
{% for meal in meals %}
{{meal.meal_value }}
{%endfor%}
- [Django]-CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true
- [Django]-Negating a boolean in Django template
- [Django]-Django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"