2013-03-26 118 views
4

我有稱爲'has_location'和'地點'的表。 'has_location'有user_haslocation_id及其自己的id,它由django自己給出。django模型對象過濾器

'地點'有更多列。

現在我想獲得某個用戶的所有位置。我所做的是..(user.id是已知的):

users_locations_id = has_location.objects.filter(user_has__exact=user.id) 
locations = Location.objects.filter(id__in=users_locations_id) 
print len(locations) 

,但我爲此print越來越0。我有數據在分貝。但我有感覺__in不接受模特身份證,是嗎?

謝謝

+0

您能向我們展示這三個模型定義的相關部分嗎? – 2013-03-26 12:01:24

+0

@GarethRees,當然,但他們只是一個正常的模型。我認爲,這裏的重點是關於我可以使用'__in''的更多信息。 – doniyor 2013-03-26 12:03:48

回答

4

您正在使用has_location自己的ID來過濾位置。你必須使用location_id s到過濾位置:

user_haslocations = has_location.objects.filter(user_has=user) 
locations = Location.objects.filter(id__in=user_haslocations.values('location_id')) 

您也可以直接通過反向關係過濾位置:

location = Location.objects.filter(has_location__user_has=user.id) 
1

什麼你的模型是什麼樣子?

您的疑問,__indoes accept已過濾的ID。

您當前密碼,解決方法:

locations = Location.objects.filter(id__in=has_location.objects.filter(user=user).values('location_id')) 
# if you just want the length of the locations, evaluate locations.count() 
locations.count() 
# if you want to iterate locations to access items afterwards 
len(locations) 
7

使用__in對於這種查詢是在Django常見的反模式:這是因爲它的簡單誘人,但它在大多數數據庫不好尺度。請參閱this presentation by Christophe Pettus中的幻燈片66ff。

用戶和位置之間有多對多的關係,用has_location表代表。你會使用ManyToManyFieldthrough表,這樣的事情通常形容這Django的:

user.locations.all() 

您可以查詢地點:

class Location(models.Model): 
    # ... 

class User(models.Model): 
    locations = models.ManyToManyField(Location, through = 'LocationUser') 
    # ... 

class LocationUser(models.Model): 
    location = models.ForeignKey(Location) 
    user = models.ForeignKey(User) 
    class Meta: 
     db_table = 'has_location' 

然後你就可以像這樣的用戶獲取位置在篩選器操作:

User.objects.filter(locations__name = 'Barcelona') 

而且你可以要求用戶相關的地點使用有效地獲取查詢集上的方法。

+0

哇,非常好。我有一個很差的數據庫知識,非常有用的指導,謝謝。 – doniyor 2013-03-26 12:32:06

+0

如果你正在編寫Django應用程序,那麼肯定值得學習數據庫。 (否則有一天你會發現你的應用程序運行速度太慢,你不知道如何修復它。)第一步是打開數據庫中的查詢日誌並在測試Django站點時監視日誌查看實際正在執行的查詢。 – 2013-03-26 12:49:08

+0

是的,你是對的。我會遵循你的指導 – doniyor 2013-03-26 13:10:46