7

'has_location'および'locations'というテーブルがあります。'has_location'は、 django自体によって与えられるuser_hasandlocation_idとそれ自身を持っています。id

「場所」にはより多くの列があります。

ここで、特定のユーザーのすべての場所を取得したいと思います。私がしたことは..(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いますprint。dbにデータがあります。__inでもモデルIDを受け入れない気がしますね。

ありがとう

4

3 に答える 3

11

この種のクエリに使用__inすることは、Djangoの一般的なアンチパターンです。その単純さのために魅力的ですが、ほとんどのデータベースでは拡張性が低くなります。ChristophePettusによるこのプレゼンテーションのスライド66ffを参照してください。

表で表されるように、ユーザーと場所の間には多対多の関係がありhas_locationます。通常、これをDjangoに説明するには、次のようなテーブルを使用ManyToManyFieldします。through

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')

prefetch_related()また、クエリセットのメソッドを使用して、ユーザーの関連する場所を効率的にフェッチするように要求できます。

于 2013-03-26T12:14:44.003 に答える
7

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)
于 2013-03-26T12:04:00.037 に答える
1

あなたのモデルはどのように見えますか?

疑わしいと思いますが、フィルタリングされたID__in を受け入れます。

現在のコードの場合、解決策は次のとおりです。

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)
于 2013-03-26T12:05:04.977 に答える