views:

42

answers:

1

I'm building a site which will provide product information in two languages: English and Chinese.

Each product must have an English name, and may also have a Chinese name.

Each time a product page is requested, the request object is inspected to determine whether the product's name should be displayed in English or Chinese. In the latter case, the Chinese name is to be displayed if set, otherwise the English name is to be displayed.

Here's a simplified version of my Product model with extraneous information removed:

class Product(models.Model):
    english_name = models.CharField(max_length=100)
    chinese_name = models.CharField(max_length=100, null=True, blank=True)

    def name(self, language):
        if language == 'Chinese' and self.chinese_name:
            return self.chinese_name
        else:
            return self.english_name

My question is what is the cleanest way to output the desired name from within a template? It's not possible to call the name method as it must be passed a language argument, and Django templates only accommodate method calls with no arguments.

I could do everything using logic within the template, but this is far from elegant:

{% ifequal language 'Chinese' %}
    {% firstof product.chinese_name product.english_name %}
{% else %}
    {{ product.english_name }}
{% endifequal %}

I could alternatively write a template filter to contain the above logic:

@register.filter
def name(product, language):
    if language == 'Chinese' and product.chinese_name:
        return product.chinese_name
    else:
        return product.english_name

This'd be fairly nice to use:

{{ product|name:language }}

Creating a template filter would get the job done, but to me this logic really belongs with the model. Is the template filter approach a good one, or is there a "better" way to achieve the same result?

I realize that my question is rather vague – I have a couple of working solutions, but I'd like to know what's considered the "best" (as in "best practice") solution to this problem.

+3  A: 

How about making a small change to the filter?

@register.filter
def name(product, language):
    return product.name(language)

This way your filter is only wrapping the call; the logic is still handled inside the model. Just a thought.

Manoj Govindan
This _is_ a good approach and the one I'd use.
Lakshman Prasad
Very nice improvement. Thanks, Manoj.
davidchambers