2013-03-26 120 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