django模型对象过滤器

don*_*yor 4 python database django django-forms

我有名为'has_location'和'locations'的表.'has_location'有user_haslocation_id它自己的id,由django本身给出.

'locations'有更多列.

现在我想获得某些用户的所有位置.我做的是..(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)
Run Code Online (Sandbox Code Playgroud)

但我得到0了这个print.我在db中有数据.但我觉得__in不接受模特身份证,是吗?

谢谢

Gar*_*ees 9

__in在Django中使用这种查询是一种常见的反模式:由于它的简单性,它很诱人,但在大多数数据库中它的扩展性很差.请参阅Christophe Pettus本演讲中的幻灯片66ff .

用户和位置之间存在多对多关系,由has_location表格表示.您通常会使用ManyToManyField带有through表格的方式将此描述为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'
Run Code Online (Sandbox Code Playgroud)

然后,您可以为这样的用户获取位置:

user.locations.all()
Run Code Online (Sandbox Code Playgroud)

您可以查询过滤器操作中的位置:

User.objects.filter(locations__name = 'Barcelona')
Run Code Online (Sandbox Code Playgroud)

您可以使用prefetch_related()查询集上的方法请求有效获取用户的相关位置.


Pav*_*sov 5

您正在使用has_location自己的ID来过滤位置。您必须使用location_id来过滤位置:

user_haslocations = has_location.objects.filter(user_has=user)
locations = Location.objects.filter(id__in=user_haslocations.values('location_id'))
Run Code Online (Sandbox Code Playgroud)

您还可以通过反向关系直接过滤位置:

location = Location.objects.filter(has_location__user_has=user.id)
Run Code Online (Sandbox Code Playgroud)