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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:35:37  来源:igfitidea点击:

django model object filter

pythondatabasedjangodjango-forms

提问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()查询集上的方法请求有效地获取用户的相关位置。