Django-rest-framework: نوعان مختلفان قليلاً من تسلسل التاريخ والوقت ISO 8601

تم إنشاؤها على ١١ يوليو ٢٠١٦  ·  3تعليقات  ·  مصدر: encode/django-rest-framework

قائمة تدقيق

  • [x] لقد تحققت من وجود هذه المشكلة مقابل فرع master من إطار عمل Django REST.
  • [x] لقد بحثت عن مشكلات مماثلة في كل من التذاكر المفتوحة والمغلقة ولا يمكنني العثور على نسخة مكررة.
  • [x] هذا ليس سؤال استخدام. (يجب توجيه هؤلاء إلى مجموعة المناقشة بدلاً من ذلك).
  • [x] لا يمكن التعامل مع هذا كمكتبة طرف ثالث. (نفضل أن تكون الوظائف الجديدة في شكل مكتبات تابعة لجهات خارجية حيثما أمكن ذلك.)
  • [x] لقد اختزلت المشكلة إلى أبسط حالة ممكنة.
  • [] لقد قمت بتضمين اختبار فاشل كطلب سحب. (إذا لم تتمكن من القيام بذلك ، فلا يزال بإمكاننا قبول المشكلة.)

    خطوات التكاثر

لا يتوافق تنفيذ تسلسل التاريخ والوقت بتنسيق ISO-8601 في قاعدة الكود.
في https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/fields.py#L1094 يتم تضمين ميكرو ثانية في القيمة التسلسلية
في https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/utils/encoders.py#L30 مللي ثانية فقط هي

سلوك متوقع

أتوقع تنفيذًا متسقًا.

السلوك الفعلي

غير متاح

Bug

التعليق الأكثر فائدة

georgejlee أستخدم عارض مخصص للتغلب على هذا:

import datetime

from rest_framework.renderers import JSONRenderer
from rest_framework.utils.encoders import JSONEncoder

class MilliSecondEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            representation = obj.isoformat()
            if obj.microsecond:
                representation = representation[:23] + representation[26:]
            if representation.endswith('+00:00'):
                representation = representation[:-6] + 'Z'
            return representation
        else:
            return super().default(obj)


class JSONRenderer(JSONRenderer):
    encoder_class = MilliSecondEncoder

حسنًا ، لم يؤثر تغيير DEFAULT_RENDERER_CLASSES إلى العارض المخصص في عرض مجموعات طرق العرض الخاصة بي. اضطررت إلى تعيين Renderer_class بشكل صريح وغريب.

ال 3 كومينتر

في الوقت الحالي ، يتطلب بعض عملاء واجهة برمجة التطبيقات (API) الخاصة بي تواريخ بدقة ملي ثانية ولا يمكنهم التعامل مع ميكروثانية. لقد حققت ذلك من خلال تعيين "DATETIME_FORMAT" على "بلا" في إعدادات DRF 3.3. الترقية إلى 3.4 يكسر هذا السلوك. هل هناك طريقة سهلة للحصول على السلوك السابق؟ لا يمكنني معرفة كيفية تحديد سلسلة تنسيق التاريخ والوقت التي تعطيني تنسيق ECMA-262. شكرا.

georgejlee أستخدم عارض مخصص للتغلب على هذا:

import datetime

from rest_framework.renderers import JSONRenderer
from rest_framework.utils.encoders import JSONEncoder

class MilliSecondEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            representation = obj.isoformat()
            if obj.microsecond:
                representation = representation[:23] + representation[26:]
            if representation.endswith('+00:00'):
                representation = representation[:-6] + 'Z'
            return representation
        else:
            return super().default(obj)


class JSONRenderer(JSONRenderer):
    encoder_class = MilliSecondEncoder

حسنًا ، لم يؤثر تغيير DEFAULT_RENDERER_CLASSES إلى العارض المخصص في عرض مجموعات طرق العرض الخاصة بي. اضطررت إلى تعيين Renderer_class بشكل صريح وغريب.

في حالة تعثر أي شخص آخر عبر هذا أثناء محاولة تكوين DRF لاستخدام برنامج تشفير مخصص عبر encoder_class مقابل datetime . كانت المشكلة التي أبقت الحل في https://github.com/encode/django-rest-framework/issues/4255#issuecomment -234560555 من العمل بالنسبة لي هي أن DRF ستستخدم برنامج التشفير المدمج إلا إذا كان الحقل DateTimeField تم تعيينه format kwarg على None أو ، إذا لم تحدد المتسلسل DateTimeField ، فأنت بحاجة إلى تعيين التكوين REST_FRAMEWORK 's مقابل DEFAULT_FORMAT: None في settings.py . عندها فقط سيتم استخدام custom encoder .

السبب هو أن حقل (حقول) المسلسل (أو عارض الحقل الافتراضي) سيتم استخدامه لتنسيق Response قبل استخدام Renderer المخصص لعرض datetime . لذلك سيكون حقل التاريخ والوقت عبارة عن سلسلة بالفعل ولن يقوم JSONEncoder الافتراضي باستدعاء المشفر المخصص ، حيث يتم التعامل مع أنواع Python الافتراضية بواسطة المشفر لذلك لن يتم استدعاء طريقة default بالبرنامج المخصص.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات