douzhuo8312
douzhuo8312
2019-06-08 17:35

使用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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • douhao2153 douhao2153 2年前

    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/
    
    点赞 评论 复制链接分享
  • dongyiyu3953 dongyiyu3953 2年前

    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

    点赞 评论 复制链接分享
  • doukao1925 doukao1925 2年前

    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 }

    点赞 评论 复制链接分享