2013-06-26 96 views
19

我正在構建一個應用程序,它可以爲位於世界各地的人們提供服務。
我正在使用Django-Rest-Framwork進行客戶端和服務器之間的通信。
所有DateTime值都以UTC格式保存到DB(我在settings.py中有USE_TZ = TrueTIME_ZONE = 'Greenwich')。Django-rest-framework時區感知渲染器/解析器

我會從用戶那裏得到他/她的當地時區。

測試 DRF時區的認識,我寫這個中間件固定的時區:

import pytz 
from django.utils import timezone 

class TimezoneMiddleware(object): 
    def process_request(self, request): 
     timezone.activate(pytz.timezone("Asia/Jerusalem")) 

的問題是:
我在這,我從用戶「START_TIME」獲得的情況下,和「end_time」字段在用戶的LOCAL時區中包含日期時間,該時區通過UnicodeJSONRendererModelSerializer,然後保存到數據庫。但是,它們被保存爲,就好像它們在UTC中一樣。

此時我希望序列化程序(或解析器)將用戶的日期時間輸入視爲需要從「亞洲/耶路撒冷」轉換爲UTC前的日期時間,然後再保存到數據庫,因爲我執行了timezone.activate(pytz.timezone("Asia/Jerusalem"))

當通過JSONParser在響應中解析數據時也是如此。
期望返回的JSON中的DateTime字段位於中間件中激活的時區中時,它們將作爲UTC返回。

如何輕鬆實現DRF?

+0

你找到一個較新的版本(普通/ serializers.py)在我的應用程序工作解? – yakxxx

+0

@yakxxx - 遺憾的是還沒有。現在我得到並返回格林尼治標準時間的日期時間值,並轉換爲本地時區在客戶端完成。 – OrPo

+0

你可以發佈請求嗎?我想知道你在JSON中使用了哪種格式?你使用的是一個可識別時區的ISO 8601字符串嗎? – codingjoe

回答

31

我有同樣的問題,並通過添加新型領域的解決了這個問題:

class DateTimeTzAwareField(serializers.DateTimeField): 

    def to_native(self, value): 
     value = timezone.localtime(value) 
     return super(DateTimeTzAwareField, self).to_native(value) 

,現在你可以在ModelSerializer使用它:

class XSerializer(serializers.ModelSerializer): 
    start = DateTimeTzAwareField() 
    end = DateTimeTzAwareField() 

    class Meta: 
     model = XModel 
     fields = (
      'id', 
      'start', 
      'end', 
     ) 
+3

一個小的修正 - 如果這個字段也可以爲空,則需要一個簡單的檢查,例如: '如果value:value = timezone.localtime(value)' – Ophir

+4

新的Django-Rest-Framework,改用'to_representation' 'to_native' – db0

+0

工程就像一個魅力,謝謝! –

14

通過@yakxxx答案似乎是最好的解決方案。 我更新之後再次發佈其與restframework

我的目錄內

from rest_framework import serializers 
from django.utils import timezone 

class DateTimeFieldWihTZ(serializers.DateTimeField): 

    def to_representation(self, value): 
     value = timezone.localtime(value) 
     return super(DateTimeFieldWihTZ, self).to_representation(value) 

from common.serializers import DateTimeFieldWihTZ 

class MyObjectSerializer(serializers.ModelSerializer): 

    start = DateTimeFieldWihTZ(format='%d %b %Y %I:%M %p') 
    end = DateTimeFieldWihTZ(format='%d %b %Y %I:%M %p') 
+0

不需要檢查Ophir建議的值是否爲None。 顯然如果值是none,這個方法永遠不會被調用 – Ramast

+0

我可以設置'DEFAULT_DATETIME_PARSER ='common.serializers。 DateTimeFieldWihTZ'將所有DatetimeField更改爲DateTimeFieldWihTZ? – kxxoling

+1

我不知道有任何與該名稱的休息框架設置 – Ramast