2015-12-14 7 views
7

संपादित करें: यह अब एक बग के रूप में मान्यता दी गई है और एक ठीक तरह कार्य प्रगति पर है यह लग रहा है: https://github.com/tomchristie/django-rest-framework/issues/3732#issuecomment-267635612DjangoRestFramework ModelSerializer DateTimeField केवल ऑब्जेक्ट निर्माण में वर्तमान समय क्षेत्र के परिवर्तित

मैं एक Django परियोजना जहाँ मैं करने के लिए उपयोगकर्ता की उम्मीद है एक निश्चित समय क्षेत्र में रहो। मेरी सेटिंग्स में TIME_ZONE = 'Asia/Kolkata' और USE_TZ = True है।

मेरे पास एक मॉडल है जिसमें डेटाटाइमफील्ड शामिल है। जब मैं पहली बार ऑब्जेक्ट बनाता हूं, तो मॉडेलरियलाइज़र +5:30 के साथ डेटाटाइम देता है। कष्टप्रद, auto_now_add=True के साथ डेटटाइम Z के पीछे यूटीसी डेटाटाइम देते हैं। मैंने फील्ड के डिफ़ॉल्ट को वर्तमान समय के लिए कॉल करने योग्य बनाकर इसे ठीक किया है।

यदि मैं किसी भी समय ऑब्जेक्ट को फिर से क्रमबद्ध करता हूं, तो सभी डेटाटाइम यूटीसी में Z के पीछे हैं। Django दस्तावेज़ीकरण से, मैं उम्मीद करता हूं कि serializer वर्तमान टाइमज़ोन का उपयोग करने के लिए, जो TIME_ZONE = 'Asia/Kolkata' द्वारा निर्धारित डिफ़ॉल्ट टाइमज़ोन पर डिफ़ॉल्ट है। मैंने get_current_timezone_name() के साथ अपने व्यू में वर्तमान टाइमज़ोन की जांच की है और यह 'Asia/Kolkata' है। मैंने अपने दृश्य में activate('Asia/Kolkata') का उपयोग करने का भी प्रयास किया है, लेकिन यूटीसी में अभी भी समय लौटाया जा रहा है।

ध्यान दें कि हर बार सही होते हैं (यूटीसी समय पहले 5:30 घंटे होते हैं), यह सिर्फ इतना है कि मैं समय बदलने के लिए अपेक्षा करता हूं। यूटीसी के समय के रूप में सभी डेटाटाइम डीबी में संग्रहीत किए जाते हैं।

क्या मुझे कुछ याद आ रहा है या यह Django Rest Framework serializers के साथ एक बग है?

उत्तर

7

प्रलेखन यहाँ पर एक नज़र डालें: http://www.django-rest-framework.org/api-guide/fields/#datetimefield

हस्ताक्षर: DateTimeField (प्रारूप = कोई नहीं, input_formats = कोई नहीं)

प्रारूप - स्ट्रिंग उत्पादन प्रारूप का प्रतिनिधित्व। यदि निर्दिष्ट नहीं है, तो यह DATETIME_FORMAT सेटिंग कुंजी के समान मान पर डिफ़ॉल्ट होता है, जो सेट होने तक 'iso-8601' होगा। एक प्रारूप स्ट्रिंग पर सेट करना इंगित करता है कि to_representation वापसी मान स्ट्रिंग आउटपुट के लिए coerced किया जाना चाहिए। स्वरूप तारों का वर्णन नीचे दिया गया है। इस मान को किसी को सेट करने से संकेत मिलता है कि पायथन डेटाटाइम ऑब्जेक्ट को to_representation द्वारा वापस किया जाना चाहिए। इस मामले में डेटाटाइम एन्कोडिंग रेंडरर द्वारा निर्धारित की जाएगी।

जब कोई नहीं के एक मूल्य प्रारूप datetime वस्तुओं के लिए प्रयोग किया जाता है to_representation और अंतिम आउटपुट प्रतिनिधित्व द्वारा लौटा दी जाएगी रेंडरर वर्ग द्वारा निर्धारित किया जाएगा।

JSON के मामले में इसका मतलब है कि डिफ़ॉल्ट डेटाटाइम प्रतिनिधित्व ईसीएमए 262 दिनांक समय स्ट्रिंग विनिर्देश का उपयोग करता है। यह आईएसओ 8601 के एक सबसेट जो मिलीसेकंड परिशुद्धता का उपयोग करता है, और 'Z' उदाहरण के लिए UTC समयज़ोन के लिए प्रत्यय, शामिल हैं: 2013-01-29T12: 34: 56.123Z।

तो आपके डेटाटाइम ऑब्जेक्ट का यूटीसी (जेड) प्रतिनिधित्व वास्तव में डिफ़ॉल्ट व्यवहार है।

जब आप या अद्यतन Djangorest के माध्यम से एक मॉडल उदाहरण बनाने , serializer data kwarg है, जो यदि आप सूची या विस्तार दृश्य का उपयोग नहीं होता है के साथ बुलाया जाएगा।

दोनों मामलों में, आपके विचार serializer.data वापस आ जाएगी। ऑपरेशन के निर्माण/अद्यतन के मामले में, यह serializer.validated_data का प्रतिनिधित्व होगा, जबकि सूची/विवरण ऑपरेशन के मामले में यह उदाहरण का प्रत्यक्ष प्रतिनिधित्व होगा।

दोनों मामलों में, डिफ़ॉल्ट kwarg format=None के साथ field.to_representation पर कॉल करके प्रतिनिधित्व प्राप्त किया जाता है, जो फ़ील्ड को सादा स्ट्रिंग मान वापस कर देगा।

जादू here होता है:

  • अद्यतन बनाने /: सत्यापन एक समयक्षेत्र अवगत वस्तु है, जो अपने मानक समय क्षेत्र शामिल हैं देता है। इसे isoformat() विधि को कॉल करके स्ट्रिंग में परिवर्तित किया गया है, और जैसा कि है।
  • सूची/ पुनर्प्राप्त करें: डीजेंगो ओआरएम टाइमस्टैम्प को यूटीसी के रूप में संग्रहीत करता है। इसे isoformat() विधि, पर कॉल करके स्ट्रिंग में परिवर्तित किया जाता है लेकिन डीआरएफ +00:00Z (ऊपर दिए गए लिंक को देखें) के साथ बदल देता है।

तो, ऑफसेट समय क्षेत्र के साथ वांछित आउटपुट प्राप्त करने के लिए आप दे सकते हैं format=None अपने serializer में DateTimeField के लिए एक कस्टम strftime स्ट्रिंग या। हालांकि, आपको हमेशा यूटीसी समय +00:00 के साथ मिल जाएगा, क्योंकि डेटा (सौभाग्य से) संग्रहीत है।

आप वास्तविक 'Asia/Kolkata' को ऑफसेट चाहते हैं, तो आप शायद अपने स्वयं के DateTimeField को परिभाषित करना होगा:

from django.utils import timezone 
class CustomDateTimeField(serializers.DateTimeField): 
    def to_representation(self, value): 
     tz = timezone.get_default_timezone() 
     # timezone.localtime() defaults to the current tz, you only 
     # need the `tz` arg if the current tz != default tz 
     value = timezone.localtime(value, timezone=tz) 
     # py3 notation below, for py2 do: 
     # return super(CustomDateTimeField, self).to_representation(value) 
     return super().to_representation(value) 
+0

यह स्पष्ट नहीं होता कि मैं क्यों ऑब्जेक्ट निर्माण के तुरंत बाद एक अलग परिणाम मिलता है। साथ ही, "वर्तमान समय क्षेत्र वह समय क्षेत्र है जिसका उपयोग प्रतिपादन के लिए किया जाता है" मुझे लगता है कि यह या तो जेएसओएन के "डिफ़ॉल्ट डेटाटाइम प्रतिनिधित्व" को ओवरराइड करता है या डीबी से पुनर्प्राप्ति के बाद डेटाटाइम को स्थानीयकृत करता है। अंत में, Django दस्तावेज़ भी स्पष्ट रूप से निर्दिष्ट करते हैं: "जब एक जागरूक डेटाटाइम को क्रमबद्ध करते हैं, तो यूटीसी ऑफसेट शामिल होता है, जैसे:" 2011-09-01T13: 20: 30 + 03: 00 ""। –

+0

सोचो मैंने इसे समझ लिया, दिलचस्प समस्या। – Geotob

+0

हम्म। Django दस्तावेज़ीकरण से मुझे आश्चर्य होगा अगर यह इरादा व्यवहार है, हालांकि ऐसा लगता है कि यह Django खुद के साथ एक मुद्दा है और DjangoRestFramework नहीं है। मैं आपके फिक्स में देख लूंगा। –

संबंधित मुद्दे