国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

如何在Django中添加沒有微秒的 DateTimeField 屬性詳解

2020-02-16 00:58:58
字體:
來源:轉載
供稿:網友

前言

今天在項目中遇到一個Django的大坑,一個很簡單的分頁問題,造成了數據重復。最后排查發現是DateTimeField 屬性引起的。

下面描述下問題,下面是我需要用到的一個 Task Model 基本定義:

class Task(models.Model): # ...... 省略了其他字段 title = models.CharField(max_length=256, verbose_name=u'標題') created_at = models.DateTimeField(auto_now_add=True, verbose_name=u'創建時間')

問題描述

前端這邊的分頁方式不是常規的 page、page_size 方式,而是使用標志位的方式進行分頁,我這里采用的就是通過創建時間的時間戳作為分頁標記。比如下面是返回的第一頁的數據:

{ "data": { "count": 5, "has_next": 1, "tasks": [ { "title": "這是一個作業標題1", "ts": 1546829224000, "id": 1 }, { "title": "這是一個作業標題2", "ts": 1546829641000, "id": 2 } ] }, "result": 1}

要請求第2頁的數據只需要在請求的 API 中傳遞上一頁最后一條數據的時間戳即可,這里我們就傳遞 1546829641000,這樣當我后臺接收到這個值過后就直接過濾大于該時間戳的數據,再取一頁數據返回前端即可,邏輯上很簡單。過濾核心代碼如下:

ts = string_utils.get_num(request.GET.get('ts', 0), 0)alltask = Task.objects.filter(created_at__gt=date_utils.timestamp2datetime(ts))

這段代碼很簡單,主要就是將前臺傳遞過來的時間戳轉換成 DateTime 類型的數據,然后利用created_at__gt來過濾,就是大于這個時間點的就可以。然后問題來了,查詢出來的數據始終包含了上一頁最后一條數據,感覺很奇怪,我這里明明用的是gt而不是gte,怎么會重復這條數據呢。

于是,我們把上一頁最后一條數據的 created_at 字段打印出來和傳遞過來的時間戳進行對比下:

>>> task = Task.objects.get(pk=2)>>> task.created_atdatetime.datetime(2019, 1, 7, 10, 54, 1, 343136)

然后將時間戳轉換成 DateTime 類型的數據:

>>> ts = int(1546829641000/1000)>>> date_utils.timestamp2datetime(ts)datetime.datetime(2019, 1, 7, 10, 54, 1)

現在看到區別沒有,從數據庫中查詢出來的 created_at 字段的值包含了一個微秒,就是后面的 343136,而時間戳轉換成 DateTime 類型的值是不包含這個微秒值的,所以我們上面查詢的使用created_at__gt來進行過濾很顯然 created_at 的值是大于下面的值的,因為多了一個微秒,所以就造成了數據重復了,終于破案了。

解決方法

那么要怎么解決這個問題呢?當然我們可以直接在數據庫中就保存一個時間戳的字段,用這個字段直接來進行查詢過濾,肯定是可以解決這個問題的。

如果就用現在的 created_at 這個 DateTimeField 類型呢?如果保存的數據沒有這個微秒是不是也可以解決這個問題啊?

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 外汇| 沿河| 基隆市| 彭水| 姜堰市| 长丰县| 扶风县| 包头市| 绵竹市| 宝鸡市| 柳林县| 丽水市| 阿拉善右旗| 扶绥县| 黔东| 雅安市| 敦化市| 河南省| 马公市| 连州市| 青阳县| 衡南县| 文登市| 南涧| 济南市| 尼木县| 山西省| 定襄县| 双鸭山市| 延川县| 永平县| 即墨市| 松潘县| 郯城县| 宜兰市| 京山县| 定结县| 白水县| 谷城县| 汝南县| 枞阳县|