0

I am creating a variable queryset and then passing the values into a dictionary context variable. I am able to convert dates but I'm not sure how to convert specific fields to currency (example: $1,000 instead of 1000) or even just humanize specific fields with commas (1,000 instead of 1000) below is my code from my view, the two methods are a part of a class:

from datetime import date

def get_context_data(self):
    context = super(MyView, self).get_context_data()
    context['myview_items'] = self.get_mymethod_items_context()
    return context

def get_mymethod_items_context(self):
    context = {}
    items = table.objects.values('date_begun', 'price', 'item_number')

    context['items'] = items
    context['headers'] = ['Date', 'Price', 'Item']
    context['fields'] = ['date_begun_date', 'price', 'item_number']
    return context

I only want to convert one field, which is what I was trying to do for the price field:

from django.contrib.humanize.templatetags.humanize import intcomma 
intcomma('price')

How im creating tables, Template tag on my template:

{% simple_table_print 'tableid1' 'Price Information' myview_items.items myview_items.fields myview_items.headers %}  
Zorpho
  • 182
  • 1
  • 14
  • could you post your model here as well? – Daniel Kravetz Malabud Aug 26 '16 at 13:55
  • Not sure relevance of the model, they are all CharField types – Zorpho Aug 26 '16 at 14:07
  • How are you planning use `items` queryset? If you want display it in template you can load `{% load humanize %}` and use `intcomma` like template tag. If you want to have a queryset with formatting price field you will need use `Func()` expressions (if your db allows it). Or you can apply `intcomma` function in for loop for all items. – Anna Aug 26 '16 at 14:27
  • I am using a template tag to create dynamic tables, so I am putting all the context variables into a template tag for a table. Not sure how to use humanize in a template tag when im just calling "myview_items.items, myview_items.headers, myview_items.fields". I guess I could try out the for loop option. I was hoping for a easier option like how I am converting date by just adding date to the end of the field name and using "from datetime import date" – Zorpho Aug 26 '16 at 14:53

3 Answers3

1

First and foremost, you should use a decimal field for your currency values if you can. This is not a django convention, it's a general programming one; decimal types can hold the necessary precision for a valid "money" representation.

As pointed by the documentation, you have to install the app humanize, and in your template, load it up with {% load humanize %}. Keep in mind that it will use the appropriate locale provided in your settings.py.

Here you have a very simple example using {% load humanize %}

Community
  • 1
  • 1
  • 1
    I have used humanize before but the way my template is setup is that humanize would do this for all fields and I only want to do this to sepecifc fields. I will update my question to show more explanation on what I mean. – Zorpho Aug 26 '16 at 15:38
1

I would install humanize app and then extend its intcomma method to create my own templatetag:

from django import template
from django.contrib.humanize.templatetags.humanize import intcomma

register = template.Library()

@register.filter
def prepend_dollars(dollars):
    if dollars:
        dollars = round(float(dollars), 2)
        return "$%s%s" % (intcomma(int(dollars)), ("%0.2f" % dollars)[-3:])
    else:
        return ''

First load your customtags.py file in your template:

{% load customtags %}

You can then use it in your template:

{{ my_decimal_val | prepend_dollars }}

Hope it helps.

user4426017
  • 1,930
  • 17
  • 31
  • 1
    I am not looking to use humanize on the template, I am wanting to convert it in the view before it gets to the template since I am calling all fields as dictionaries to my template – Zorpho Aug 26 '16 at 15:53
  • You could just call `prepend_dollars` method in your python view code if you do not want to use it in template. – user4426017 Aug 26 '16 at 15:59
0

Usually it's a payment processor headache. But if you want to localize your currency value I'd suggest sth like that:

Use 'babel' app as a base & implement the following filter:

from decimal import Decimal
from decimal import InvalidOperation

from babel.numbers import format_currency
from django.utils.translation import get_language, to_locale


@register.filter
def currency_format(value, currency = 'USD'):
    try:
        value = Decimal(value)
    except (TypeError, InvalidOperation):
        return u''        

    kwargs = {
        'currency': currency,
        'locale': to_locale(get_language() or settings.LANGUAGE_CODE)

    return format_currency(value, **kwargs)

You can use it as a filter or in your views by calling currency_format() directly.

Dmitry
  • 432
  • 2
  • 6