Django-rest-framework: Dua serialisasi datetime iso 8601 yang sedikit berbeda

Dibuat pada 11 Jul 2016  ·  3Komentar  ·  Sumber: encode/django-rest-framework

Daftar Periksa

  • [x] Saya telah memverifikasi bahwa masalah itu ada terhadap master cabang kerangka kerja REST Django.
  • [x] Saya telah mencari masalah serupa di tiket terbuka dan tertutup dan tidak dapat menemukan duplikatnya.
  • [x] Ini bukan pertanyaan penggunaan. (Itu harus diarahkan ke grup diskusi sebagai gantinya.)
  • [x] Ini tidak dapat ditangani sebagai perpustakaan pihak ketiga. (Kami lebih suka fungsionalitas baru dalam bentuk pustaka pihak ketiga jika memungkinkan.)
  • [x] Saya telah mengurangi masalah ini menjadi kasus yang sesederhana mungkin.
  • [] Saya telah menyertakan tes yang gagal sebagai permintaan tarik. (Jika Anda tidak dapat melakukannya, kami masih dapat menerima masalah tersebut.)

    Langkah-langkah untuk mereproduksi

Penerapan serialisasi datetime dalam format ISO-8601 tidak konsisten di basis kode.
Dalam https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/fields.py#L1094 mikrodetik disertakan dalam nilai serial
Di https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/utils/encoders.py#L30 hanya milidetik yang

Perilaku yang diharapkan

Saya mengharapkan implementasi yang konsisten.

Perilaku sebenarnya

T / A

Bug

Komentar yang paling membantu

@georgejlee Saya menggunakan perender khusus untuk mengatasi ini:

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

Hmm, mengubah DEFAULT_RENDERER_CLASSES menjadi perender khusus tidak memengaruhi rendering kumpulan tampilan saya. Harus menyetel renderer_class secara eksplisit, aneh.

Semua 3 komentar

Saat ini beberapa klien API saya memerlukan tanggal dengan presisi milidetik dan tidak dapat menangani mikrodetik. Saya mencapai ini dengan menetapkan 'DATETIME_FORMAT' ke Tidak Ada di pengaturan untuk DRF 3.3. Mengupgrade ke 3.4 menghentikan perilaku ini. Adakah cara mudah untuk mendapatkan perilaku sebelumnya? Saya tidak tahu cara menentukan string format datetime yang memberi saya format ECMA-262. Terima kasih.

@georgejlee Saya menggunakan perender khusus untuk mengatasi ini:

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

Hmm, mengubah DEFAULT_RENDERER_CLASSES menjadi perender khusus tidak memengaruhi rendering kumpulan tampilan saya. Harus menyetel renderer_class secara eksplisit, aneh.

Jika ada orang lain yang tersandung saat mencoba mengonfigurasi DRF untuk menggunakan pembuat enkode khusus melalui encoder_class untuk datetime . Masalah yang membuat solusi di https://github.com/encode/django-rest-framework/issues/4255#issuecomment -234560555 tidak berfungsi untuk saya adalah DRF akan menggunakan encoder bawaannya kecuali jika bidang DateTimeField memiliki format kwarg disetel ke None ATAU, jika Anda tidak menentukan DateTimeField serializers, maka Anda perlu menyetel konfigurasi REST_FRAMEWORK untuk DEFAULT_FORMAT: None dalam settings.py . Hanya dengan begitu custom encoder akan digunakan.

Alasannya adalah, field serializer (atau default field renderer) akan digunakan untuk memformat Response sebelum custom Renderer digunakan untuk membuat datetime . Jadi bidang datetime akan menjadi string dan JSONEncoder default tidak akan memanggil pembuat enkode khusus, karena jenis Python default ditangani oleh pembuat enkode sehingga metode default pembuat enkode khusus tidak akan dipanggil.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat