2014-09-28 6 views

Odpowiedz

8

będziemy chcieli napisać custom serializer field, tak:

class TimestampField(serializers.Field): 
    def to_native(self, value): 
     epoch = datetime.datetime(1970,1,1) 
     return int((value - epoch).total_seconds()) 

Aby obsługiwać operacje zapisu, które chcesz dziedziczyć po WritableField, a także wdrożyć from_native().

+1

AFAIK datetime są przechowywane w bazie danych w postaci liczby . Miałem nadzieję, że otrzymam ten numer zamiast konieczności powtarzania wszystkich rekordów w zapytaniu. Obawiam się, że będą miały wpływ na wyniki zarówno dla tego, jak i mojego własnego podejścia. – elewinso

+3

Jeśli otrzymasz tę odpowiedź i używasz DRF 3.x, metoda 'to_native' jest teraz' to_representation' –

1

Chociaż wolę odpowiedź udzieloną przez Toma Christie, ponieważ jest bardziej odporna. postanowiłem zamieścić moje rozwiązania z korzyścią dla potencjalnych czytelników

response_date = serializers.SerializerMethodField('get_timestamp') 
def get_timestamp(self, obj): 
    #times 1000 for javascript. 
    return time.mktime(obj.updated_at.timetuple()) * 1000 
3

I nie był w stanie uzyskać przykład Tomka do pracy i wydawało się, że wartości te nie były modyfikowane. Jednak to mi wyjściowej i po pewnym odczytu I znaleźć drogę do wytworzenia pożądanego efektu:

[Metoda 1]

serializers.py

import time 

class TimestampField(serializers.Field): 
    def to_representation(self, value): 
     return int(time.mktime(value.timetuple())) 

class MySerializer(serializers.ModelSerializer): 
    ts = TimestampField(source="my_fieldname") #Source must be a models.DateTimeField 

    class Meta: 
     model = myModel 
     fields = ('id', 'ts') 

wyjście JSON:

[{ 
    "id": 1, 
    "ts": 1475894303 
}, 
{ 
    "id": 2, 
    "ts": 1475833070 
}] 

[Metoda 2]

Wyjaśnienie Toma i poprzednia wspomniana metoda są zdecydowanie bardziej na czasie przy zachowaniu standardów (ponieważ wyniki są faktycznie typu integer).

Jednak szybkie i brudne rozwiązanie polega na podaniu wartości format parameter for the DateTimeField i ustawieniu wartości w sekundach.

Uwaga: prawdopodobnie to nie będzie działać poprawnie na komputerach z systemem Windows! A może skutkować ValueError: Nieprawidłowy format string

Aby go wypróbować właśnie to "Format" parametr słowo kluczowe w polu serializer tak:

serializers.py wyjście

class MySerializer(serializers.ModelSerializer):  
    timestamp = serializers.DateTimeField(format="%s") 

    class Meta: 
     model = myModel 
     fields = ('id', 'ts') 

JSON:

[{ 
    "id": 1, 
    "ts": "1475890361" 
}, 
{ 
    "id": 2, 
    "ts": "1475833070" 
}] 

Dodatkowo można dołączyć mikrosekund:

timestamp = serializers.DateTimeField(format="%s.%f") 

Jeśli chcesz przetestować funkcjonalność w swoim własnym tłumacza (w celu sprawdzenia systemu operacyjnego to umożliwia % s parametr) po prostu skopiować na te linie:

import datetime 
print datetime.datetime.now().strftime('%s') #datetime formatted as seconds for REST 

import time #This is just for confirmation 
print time.mktime(datetime.datetime.now().timetuple()) #time object result as float 

Uważam, że ta metoda jest trochę niezgodna z pytaniem o OP, ponieważ wynik nie jest faktycznie liczbą całkowitą, zamiast tego jest ciągiem reprezentującym liczbę całkowitą/zmiennoprzecinkową - a REST będzie grzecznie dodawał cytaty wokół wartości.

2

Globalna konfiguracja:

REST_FRAMEWORK = { 
    'DATETIME_FORMAT': '%s.%f', 
} 
0
REST_FRAMEWORK = { 
    # if you want with milliseconds or 
    'DATETIME_FORMAT': '%s.%f', 
    # only with seconds 
    'DATETIME_FORMAT': '%s', 
} 

wynik w reszta będzie

1) +1517863184,666435

2) 1517863249