Django通過session實現多語言切換

Creabine發表於2017-01-18

  公司官網需要多語言支援(中文/英文),瞭解了一通之後,發現Django雖然有自帶的國際化多語言功能,但是僅限於翻譯單詞,官網這種有很多大段落介紹的內容,就不太適合了。所以自己來實現。

  實現的思路也很簡單,就是中英文使用不同的模板,在命名上進行區別,如index.htmlindex_en.html,然後在使用者的session中加入config物件,包含language和templateName兩個屬性,分別記錄 語言 和 當前模板名稱。每次收到request的時候,都校驗一下session,從中取出語言和模板設定,然後返回相應的html檔案即可。

先記錄一下session的讀寫使用:
# 建立或修改 session:
request.session[key] = value
# 獲取 session:
request.session.get(key,default=None)
# 刪除 session
del request.session[key] # 不存在時報錯

另外請注意注意: Django的session有個大坑!!!session有下邊三個引數:

1、SESSION_SAVE_EVERY_REQUEST
如果設定為True,django為每次request請求都儲存session的內容,預設為False。
2、SESSION_EXPIRE_AT_BROWSER_CLOSE
如果設定為True,瀏覽器已關閉session就過期了,預設為False。
3、SESSION_COOKIE_AGE
設定SESSION的過期時間,單位是秒,預設是兩週

  發現沒,Django預設情況下,只有session在增刪的時候,才會儲存。如果僅僅改變值,那麼不會觸發儲存,所以一定要在settings.py中修改1的設定,不然切換語言之後,實際上無法正確儲存在session中。

  將1設定為True之後,Django將在每次收到請求之後都儲存session,不論它的值是否變化。但是這樣的話,似乎又影響了效率,我們只要在需要的時候儲存就可以了。那麼還有一個方式,在儲存之後,設定request.session.modified = True 來顯式的告訴Django值改變了,這樣Django就會進行儲存了。

教程
參考資料

下面是核心程式碼:
# index頁面比較特殊,第一次進入時request.path是‘/’,在網站內切回的時候是‘index’
def index(request):
    #訪問網址時預設彈出首頁
    if request.path == '/':
        user_config = getUserConfig(request)
        request.session["user_config"]['thisTemplateName'] = 'index'
        if user_config['language'] == 'Chinese':
            TemplateName = 'index.html'
        else:
            TemplateName = 'index_en.html'
        return render(request, TemplateName)
    #在網站內跳轉至首頁
    else:
        templateName = getTemplateByLanguage(request)
        return render(request,templateName)


#下邊兩個是  關於我們   和   聯絡我們  的跳轉
def AboutUs(request):
    templateName = getTemplateByLanguage(request)
    return render(request,templateName)

def ContactUs(request):
    templateName = getTemplateByLanguage(request)
    return render(request,templateName)

#改變語言,更新session,並跳轉至當前頁
#這裡要注意,跳轉到當前頁是為了防止這種情況:更改語言之後重新整理頁面,相當於又發了一次更改語言的請求。
def ChangeLanguage(request):
    user_config = getUserConfig(request)
    if user_config['language'] == 'Chinese':
        user_config['language'] = 'English'
        templateName = user_config['thisTemplateName'] + '_en.html'
    else:
        user_config['language'] = 'Chinese'
        templateName = user_config['thisTemplateName'] + '.html'
    # 語言改變後改變session 和 cookie
    request.session['user_config'] = user_config
    request.session.modified = True
    return render(request, templateName)

#根據語言取得要跳轉到的模板
def getTemplateByLanguage(request):
    user_config = getUserConfig(request)
    nextTemplateName =  request.path[1:-5]
    #得到新模板之後,存入session
    request.session["user_config"]['thisTemplateName'] = nextTemplateName
    request.session.modified = True
    if user_config['language'] == 'Chinese':
        return request.path[1:-5] + '.html'
    else:
        return request.path[1:-5] + '_en.html'


# 主要目的是得到使用者當前的語言,頁面只是順便取了,實際上在getTemplateByLanguage 函式中決定
def getUserConfig(request):
    user_config = ''
    # 若session存在則用session
    if(request.session.get("user_config")):
          user_config = request.session["user_config"]
    # 若session不存在則使用   系統預設語言   和   index  頁面作為預設config,並存入session
    else:
        userLanguage = request.environ.get('HTTP_ACCEPT_LANGUAGE').split(',', 1)[0]
        if userLanguage == 'zh-CN' or userLanguage == 'zh':
            user_config = {'language': 'Chinese','thisTemplateName': 'index'}
        else:
            user_config = {'language': 'English','thisTemplateName': 'index'}
        request.session['user_config'] = user_config
        request.session.modified = True
    return user_config



相關文章