Django模型对象fi

2024-05-05 00:33:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有叫“has_location”和“locations”的表has{u location'有user_haslocation_id以及它自己的id,由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)

但是我通过这个得到了0。我有数据库数据。但我觉得__in不接受模型id,是吗?

谢谢


Tags: django用户inidlenobjectslocationfilter
3条回答

对这种查询使用__in在Django中是一种常见的反模式:它很诱人,因为它很简单,但是在大多数数据库中伸缩性很差。请参阅this presentation by Christophe Pettus中的幻灯片66ff。

用户和位置之间存在多对多关系,由has_location表表示。通常,您会使用带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'

然后您可以获取用户的位置,如下所示:

user.locations.all()

您可以查询筛选操作中的位置:

User.objects.filter(locations__name = 'Barcelona')

您还可以请求使用查询集上的^{}方法有效地获取用户的相关位置。

你的模特长什么样?

对于您的疑问,__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)

您正在使用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'))

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

location = Location.objects.filter(has_location__user_has=user.id)

相关问题 更多 >