Python django 模型对象过滤器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15636527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
django model object filter
提问by doniyor
I have tables called 'has_location' and 'locations'. 'has_location' has user_hasand location_idand its own idwhich is given by django itself.
我有名为“has_location”和“locations”的表。'has_location' has user_hasandlocation_id和它自己的id,由 django 本身给出。
'locations' have more columns.
“位置”有更多的列。
Now I want to get all locations of some certain user. What I did is..(user.id is known):
现在我想获取某个特定用户的所有位置。我所做的是..(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)
but I am getting 0by this print. I have data in db. but I have the feeling that __indoes not accept the models id, does it ?
但我正在接受0这个print。我在数据库中有数据。但我有一种__in不接受模型 ID的感觉,是吗?
thanks
谢谢
采纳答案by Pavel Anossov
You are using has_location's own id to filter locations. You have to use location_ids to filter locations:
您正在使用 has_location 自己的 id 来过滤位置。您必须使用location_ids 来过滤位置:
user_haslocations = has_location.objects.filter(user_has=user)
locations = Location.objects.filter(id__in=user_haslocations.values('location_id'))
You can also filter the locations directly through the reverse relation:
您还可以通过反向关系直接过滤位置:
location = Location.objects.filter(has_location__user_has=user.id)
回答by okm
What do your models look like?
你的模型是什么样的?
For your doubt, __indoes acceptfiltered ids.
对于您的疑问,__in是否接受过滤的 ID。
For your current code, the solution:
对于您当前的代码,解决方案:
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)
回答by Gareth Rees
Using __infor this kind of query is a common anti-pattern in Django: it's tempting because of its simplicity, but it scales poorly in most databases. See slides 66ff in this presentation by Christophe Pettus.
使用__in这种类型的查询是在Django常见的反模式:这是诱人的,因为它的简单,但它在大多数数据库不佳扩展。请参阅Christophe Pettus 的演示文稿中的幻灯片 66ff 。
You have a many-to-many relationship between users and locations, represented by the has_locationtable. You would normally describe this to Django using a ManyToManyFieldwith a throughtable, something like this:
用户和位置之间存在多对多关系,如has_location表所示。您通常会使用ManyToManyField带有through表格的a 向 Django 描述这一点,如下所示:
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'
Then you can fetch the locations for a user like this:
然后您可以像这样获取用户的位置:
user.locations.all()
You can query the locations in your filter operations:
您可以在过滤操作中查询位置:
User.objects.filter(locations__name = 'Barcelona')
And you can request that users' related locations be fetched efficiently using the prefetch_related()method on a query set.
并且您可以使用prefetch_related()查询集上的方法请求有效地获取用户的相关位置。

