2013-06-26 10 views
19

世界中のさまざまな場所にいる人々にサービスを提供するアプリを開発しています。
私はクライアントとサーバー間の通信にDjango-Rest-Framworkを使用しています。
すべてのDateTime値は、UTCとしてDBに保存されています(settings.pyにはUSE_TZ = TrueTIME_ZONE = 'Greenwich'があります)。Django-rest-frameworkタイムゾーン対応レンダラー/パーサー

私は自分のローカルタイムゾーンから取得します。問題がある

import pytz 
from django.utils import timezone 

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

私は一定の時間帯で、このミドルウェアを書いたタイムゾーンの認識のためのテスト DRF に私は、ユーザー「のstart_time」から取得していた場合を持って
と「end_time」フィールドには、ユーザーのLOCALのタイムゾーンが含まれ、UnicodeJSONRendererからModelSerializerに移動し、DBに保存されます。ただし、それらはUTC
のように保存されます。

timezone.activate(pytz.timezone("Asia/Jerusalem"))を実行して以来、シリアライザ(またはパーサー)はdatetimeをユーザーに入力してDBに保存する前に、「アジア/エルサレム」からUTCに変換する必要があります。

JSONParserによってデータが応答で解析された場合も同様です。
返されたJSONのDateTimeフィールドがミドルウェアでアクティブになっているタイムゾーンにあると予想されている間は、UTCとして返されます。

どうすればDRFで簡単に達成できますか?

+0

あなたが見つけますか溶液? – yakxxx

+0

@yakxxx - 残念ながらまだありません。今のところ、私はGMTのdatetime値を取得して返し、ローカルタイムゾーンへの変換はクライアントの側で行われます。 – 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

小規模な修正 - このフィールドもnullでもかまいません。例えば、 'if value:value = timezone.localtime(value)' – Ophir

+4

新しいDjango-Rest-Frameworkは、代わりに 'to_representation'を使用します。 「to_native」の – db0

+0

魅力のように動作します、ありがとう! –

14

を@yakxxxによって答えがあると思われます最高のソリューション。 私は自分のアプリケーション内(共通/ serializers.py)それは私のディレクトリ内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を設定できますか?すべてのDatetimeFieldをDateTimeFieldWihTZに変更するには、「DateTimeFieldWihTZ」? – kxxoling

+1

私は、その名前のレストフレームワークの設定に気づいていません – Ramast

関連する問題