don*_*yor 4 python database django django-forms
我有名为'has_location'和'locations'的表.'has_location'有user_has和location_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不接受模特身份证,是吗?
谢谢
__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()查询集上的方法请求有效获取用户的相关位置.
您正在使用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)