tags:

views:

193

answers:

2

Is there a way to force django to display nothing instead of "None" for a Decimal Field that's been left blank?

In my template, I show a list of all the values for a particular field. Each value is hyperlinked to a page that displays the results of a query filtered on that value. But because there are some entries with null value, my list includes actual DecimalField entries and "None" for all those that are empty. When a user clicks on None, django throws a validation error because you cannot query a DecimalField using a string.

I could write if statements checking all instances of decimal fields for Nones and skipping them, but that is far from an elegant solution. Any advice?

This is one part of the code, though there are other templates that derive the None value in slightly different manners:

{% for item in choices %}
    <a href={% url app_views.field_choice item %}>{{ item }}</a><br>
{% endfor %}
+1  A: 

If you don't want to filter the list of values, you could use the built-in default or default_if_none template filters to control what's displayed, but with the example given above, you'd end up with empty links.

{{ item|default_if_none:"" }}

Given your need to hyperlink and query on each value and a view which is going to show an error if not given a number, I'd filter the list when you're passing it to the template context:

{"choices": [choice in choices where choice is not None]}
insin
A: 

Ok, so lets say you get Django to return an empty string instead od None for empty values.

So now what happens with this code:

{% for item in choices %}
<a href={% url app_views.field_choice item %}>{{ item }}</a><br>
{% endfor %}

You will either:

  • Get a bunch of empty links (<a href="/field_choice/"></a>)
  • Or an exception form the url reverse mechanism (because the positional argument is required).

The method you don't want to use is much (!) more elegant:

{% for item in choices %}
    {% if item %}
        <a href={% url app_views.field_choice item %}>{{ item }}</a><br>
    {% endif %}
{% endfor %}

Of course you are also free to build a list without empty items beforehand: in the view, or even using a custom manager.

Ludwik Trammer
Well since None only shows up once, I would only get one empty link which would be invisible to the user.Adding the 1 if statement to the loop would be fine, but if/when I expand the template to specifically reference the individual fields (as opposed to looping through them dynamically), I'd have to write an if statement for every field reference that could contain a None.
Ed
It's a really bad practice to count on links not being visible to the user, just because they are empty. They are still there, and there are tons of situations when they will be used.
Ludwik Trammer
Agreed. I changed the view to filter out values in the list that are None. Then I used the default_if_none filter for templates that aren't pre-filtered
Ed