兩張通過外鍵聯系的表,如何在一張表上根據另一張表上的屬性查找滿足條件的對象集?
1 平常查找表中數據的條件是python中已有的數據類型,通過名字可以直接查找。如果條件是表中外鍵列所對應表的某一列,該如何查詢數據?
假設表1是新聞表,是回復表中某一外鍵指向的表,表2是回復表。
class News(models.Model): title = models.CharField(max_length=50); summary = models.TextField(); url = models.CharField(max_length=150); favorCount = models.IntegerField(default=0); favorUsername = models.TextField(default=""); replyCount = models.IntegerField(default=0); class Reply(models.Model): content = models.TextField(); user = models.ForeignKey('User'); newID = models.ForeignKey('News'); replyTime = models.DateTimeField(auto_now_add=True); def __unicode__(self): return self.content;
問題1:根據表1的某些條件來查找表2的對象集。
如:想要查找對於新聞id是3的所有回復
方法一、首先獲得外鍵指向的表中對象,然后通過‘_set’這樣的方法獲得目標表中的數據。
obj = News.objects.get(id=3) replys = obj.reply_set.all() # 或直接一句: replys = News.objects.get(id=3).reply_set.all()
方法二、直接在目標表中通過雙下划線來指定外鍵對應表中的域來查找符合條件的對象。
models.Reply.objects.filter(newID__id=3)
問題2: 根據表2的某些條件查找表1的對象集。此時需要將表2的名字小寫加兩個下划線,再加上查找條件。比如:查找回復內容中包含“new”的所有新聞
News.objects.filter(reply__content__contains='new');
在filter中可以這樣用,在values方法中也可以這樣使用,此時的值便是外鍵對應表中的數據。
2 在使用django中避免不了要跟前台進行數據交互,而python中的數據類型豐富,比如datetime模塊的datetime類型就不可以json編碼,如果想要繼續json格式化,有兩種方法可以解決,1)使用django提供的格式化 2)自己編寫編碼器或默認處理函數。
注意:pyhton中json只會編碼python中自己的數據類型,比如數字、字符串、元組、列表、字典等。在django中處理數據經常遇到queryset這類數據,需要先將他轉化成列表再json編碼。[list(queryset)]
方法一、所以需要更強勁的django.core提供的serializers.serialize方法,一般使用json格式就是serializers.serialize('json',data)。可以很方便的將django中所有數據類型進行json格式編碼。
方法二、自己編寫編碼器或者寫默認處理函數
1)寫自己的編碼器類
class MyJSONEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime.datetime): return (datetime.timedelta(hours=8)+obj).strftime('%Y-%m-%d %H:%M:%S'); elif isinstance(obj, datetime.date): return obj.strftime("%Y-%m-%d") else: return json.JSONEncoder.default(self, obj)
2)寫自己的默認處理函數
def myDumps(obj): if isinstance(obj, datetime.datetime): return (datetime.timedelta(hours=8)+obj).strftime('%Y-%m-%d %H:%M:%S'); else: return json.dumps(obj);
對其進行測試
t = datetime.datetime.utcnow(); a=[1,2,43,56]; print json.dumps(t,default=myDumps); print json.dumps(a,default=myDumps); a.extend([t,t+datetime.timedelta(hours=8)]); print json.dumps(t,default=myDumps); print json.dumps(a,cls=MyJSONEncoder);
測試結果
"2016-06-26 09:53:03" [1, 2, 43, 56] "2016-06-26 09:53:03" [1, 2, 43, 56, "2016-06-26 09:53:03", "2016-06-26 17:53:03"]