使用JSON将Django日期时间传递到Golang服务器
Here is my django model
class Data(models.Model):
created = models.DateTimeField(null=True, blank=True, editable=False)
modified = models.DateTimeField(null=True, blank=True)
raw = models.TextField(null=True, blank=True)
uuid = models.CharField(blank=True, null=True, max_length=48,unique=True)
used = models.BooleanField(default=False,null=True)
name = models.CharField(blank=True, null=True, max_length=200)
geohash = models.CharField(blank=True, null=True, max_length=200)
def __str__(self):
return str(self.created) + ":" + str(self.raw)
def __unicode__(self):
return str(self.created) + ":" + str(self.raw)
def save(self, *args, **kwargs):
""" On save, update timestamps """
if not self.uuid :
self.uuid = str(uuid.uuid4().hex) +str(random.randint(1000,9999) )
if not self.id:
self.created = timezone.now()
self.modified = timezone.now()
# if not self.geoHash and (self.gpsLat and self.gpsLong):
# Geohash.encode(self.gpsLat, self.gpsLong)
return super(DataLbc, self).save(*args, **kwargs)
def toJson(self):
ret = {}
ret["Created"] = str(self.created)
ret["Modified"] = str(self.modified)
ret["Used"] = self.used
ret["Raw"] = self.raw
return ret
Here is the way that i send it to my golang server :
from RawOffer.models import Data
while True:
try :
for data in Data.objects.all()[:10]:
requests.post("http://127.0.0.1:8087/convert/",json=data.toJson())
except Exception as e:
print(e)
time.sleep(5)
Now my golang server :
package main
import (
"database/sql"
"encoding/json"
"fmt"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/jmoiron/sqlx"
"github.com/lib/pq"
"strings"
"gopkg.in/guregu/null.v3"
)
type RawOffer struct {
RawOfferData string `json:"Raw"`
Modified null.Time `json:"Modified"`
Created null.Time `json:"Created"`
}
func convertLbc(c *gin.Context) {
var rawOffer RawOffer
c.BindJSON(&rawOffer)
fmt.Println(rawOffer.Created)
var err error
s := strings.Split(rawOffer.RawOfferData, `"ads": `)
s2 := `{ "ads": ` + s[1]
result := strings.Replace(s2, `, "status": "ready"}]`, ``, -1)
//fmt.Println(result)
var rawOfferLbc RawOfferLbc
if err = json.Unmarshal([]byte(result), &rawOfferLbc); err != nil {
fmt.Println(result)
panic(err)
}
}
var db *sqlx.DB
func main() {
var err error
fmt.Println("begin")
r := gin.Default()
r.Use(cors.Default())
r.POST("/convert/",convert)
r.Run((":8087"))
}
but for Created and modified when i try to receive it i have {0001-01-01 00:00:00 +0000 UTC false}
How to serialize a django datetime to send it in json and how to get it in golang?
My main goal so is to send an object with the date from the django app to a microservice in golang. So I need to serialize the django date and I need to write a lot of text because stackoverflow won't let me post my program if i don't write enough text ...
Regards
Here is a working example related to the question that could be helpful to someone in the future.
server.go
package main
import (
"fmt"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/jmoiron/sqlx"
"gopkg.in/guregu/null.v3"
"strconv"
)
type RawOffer struct {
Used_f bool `json:"Used_f"`
Used_t bool `json:"Used_t"`
RawOfferData string `json:"Raw"`
Modified null.Time `json:"Modified"`
Created null.Time `json:"Created"`
}
func convert(c *gin.Context) {
var rawOffer RawOffer
c.BindJSON(&rawOffer)
fmt.Println(`Used_f = ` + strconv.FormatBool(rawOffer.Used_f))
fmt.Println(`Used_t = ` + strconv.FormatBool(rawOffer.Used_t))
fmt.Println(`RawOfferData = `, rawOffer.RawOfferData)
fmt.Println(`Modified = `, rawOffer.Modified)
fmt.Println(`Created = `, rawOffer.Created)
}
var db *sqlx.DB
func main() {
fmt.Println("begin")
r := gin.Default()
r.Use(cors.Default())
r.POST("/convert/", convert)
r.Run((":8087"))
}
test.py
import requests
import json
import datetime
def default(o):
if isinstance(o, (datetime.date, datetime.datetime)):
return o.isoformat() + 'Z'
try :
data = dict(
Created = datetime.datetime.utcnow(),
Modified = datetime.datetime.utcnow(),
Used_f = False,
Used_t = True,
Raw = 'some raw data here',
)
datastr = json.dumps(data, default=default)
print(datastr)
requests.post("http://127.0.0.1:8087/convert/", datastr)
except Exception as e:
print(e)
Log on test.py:
$ python test.py
{"Created": "2019-06-09T15:48:38.978230Z", "Modified": "2019-06-09T15:48:38.978689Z", "Used_f": false, "Used_t": true, "Raw": "some raw data here"}
Log on Server:
begin
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] POST /convert/ --> main.convert (4 handlers)
[GIN-debug] Listening and serving HTTP on :8087
Used_f = false
Used_t = true
RawOfferData = some raw data here
Modified = {2019-06-09 15:48:38.978689 +0000 UTC true}
Created = {2019-06-09 15:48:38.97823 +0000 UTC true}
[GIN] 2019/06/09 - 11:48:39 |[97;42m 200 [0m| 16.979399ms | 127.0.0.1 |[97;46m POST [0m /convert/
by default django datetime field had timezone support. you need think other way . or you can use django-extentions . this third party package comes with a created and modified datetime field which is don't record timezone, use those two field you will get output like {0001-01-01 00:00:00 }
I've used a dirty trick to serialize the date :
def toJson(self):
ret = {}
date_handler = lambda obj: (
obj.isoformat()
if isinstance(obj, (datetime.datetime, datetime.date))
else None
)
ret["Created"] = str(json.dumps(self.created, default=date_handler)).replace("\"","")
ret["Modified"] = str(json.dumps(self.modified, default=date_handler)).replace("\"","")
ret["Used"] = self.used
ret["Raw"] = self.raw
return ret
I hope someone will find a better solution