简体   繁体   中英

Set language code inside a view in django

How do I set the language code inside a view (in django)?

I'm sending a HttpResponse that contains a python-date.strftime("%A") .

%A is the day (eg 'Monday'), but I want to get the day in Swedish instead of English.

The documentation for locale suggests that fiddling with the locale too much is a bad idea:

It is generally a bad idea to call setlocale() in some library routine, since as a side effect it affects the entire program. Saving and restoring it is almost as bad: it is expensive and affects other threads that happen to run before the settings have been restored.

If it's okay for your entire application to use the Swedish locale, you should just set it once and be on your way. On the other hand if you only want that page to use the Swedish locale or you need to be able to switch on a per-request basis, locale and consequently datetime.strftime aren't the way to go. The reason for this limitation seems to be that python calls into the C runtime for strftime which doesn't play well with a frequently changing locale.

Provided your needs are relatively limited, your best bet is to write your own function that formats dates the way you want them without leaning on strftime for any of the locale specific specifiers {%a, %A, %b, %B, %c, %p} . This will probably entail building a list of locale specific month/day names, but that's not that big a deal.

Here's a really basic implementation that lets you switch between English and French (I don't have the Swedish locale installed ;) and handles %a and %b and calls down to datetime.strftime for everything else:

import datetime

def wrap_strftime(d, fmt, locale = "en"):
    """
    Preprocess a strftime format so we can pass in the locale.

    >>> dt = datetime.datetime(2010, 1, 1)
    >>> wrap_strftime(dt, "%a %b %d, %Y")
    'Fri Jan 01, 2010'
    >>> wrap_strftime(dt, "%a %b %d, %Y", "fr")
    'Ven jan 01, 2010'
    """

    data = {
        "fr": {
            "%a": ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'],
            "%b": [
                'jan', 'f\xc3\xa9v', 'mar', 'avr', 'mai', 'jui',
                'jul', 'ao\xc3\xbb', 'sep', 'oct', 'nov', 'd\xc3\xa9c'
            ],
        },
        "en": {
            "%a": ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
            "%b": [
                'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
            ],
        },
    }

    getters = {
        "%a": lambda dt: dt.weekday(),
        "%b": lambda dt: dt.month - 1,
    }


    for pattern in data[locale]:
        getter = getters[pattern]
        fmt = fmt.replace(pattern, data[locale][pattern][getter(d)])

    return d.strftime(fmt)

if __name__ == "__main__":
    import doctest
    doctest.testmod()

You probably also want to check out Babel which will be much more robust than trying to wrap strftime and lets you do things like:

>>> from babel.dates import format_datetime
>>> import datetime
>>> format_datetime(datetime.datetime.now(), "EEE dd MMM yyyy", locale="fr")
u'lun. 03 mai 2010'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM