简体   繁体   English

如何按来自不同表的值对 django 查询集进行排序?

[英]How can I sort a django queryset by a value from a different table?

I have these models:我有这些模型:

class NHLTeam(models.Model):
    team_name = models.CharField(max_length=50)
    team_id = models.IntegerField()  # The NHL API gives each team an id. Probably useful to save it.
    city = models.CharField(max_length=50)

class NHLGame(models.Model):
    home_team = models.ForeignKey(NHLTeam, on_delete=models.CASCADE, related_name="home_team")
    away_team = models.ForeignKey(NHLTeam, on_delete=models.CASCADE, related_name="away_team")
    date = models.DateField()

class Distance(models.Model):
    destination = models.ForeignKey(NHLTeam, on_delete=models.CASCADE)
    starting_country = models.CharField(max_length=2,
                                        choices=COUNTRY_CHOICES)
    starting_province = models.CharField(max_length=50)
    starting_city = models.CharField(max_length=50)
    distance = models.DecimalField(decimal_places=1, max_digits=6)

So basically NHLTeam just contains the 31 teams currently in the NHL.所以基本上 NHLTeam 只包含目前在 NHL 中的 31 支球队。 NHLGame represents an actual game which contains a home_team, away_team and a date. NHLGame 代表一个包含主队、客队和日期的实际比赛。 Distance contains the distance from the city the user lives in to the team.距离包含用户居住的城市到团队的距离。 If I get a list of the NHLGames with NHLGame.objects.all() I get this:如果我使用NHLGame.objects.all()获得 NHLGames 列表,我会得到以下信息:

<QuerySet [<NHLGame: 2021-02-05: Boston Bruins @ Philadelphia Flyers>, <NHLGame: 2021-02-05: Detroit Red Wings @ Tampa Bay Lightning>, <NHLGame: 2021-02-05: Nashville Predators @ Florida Panthers>, <NHLGame: 2021-02-05: Los Angeles Kings @ Vegas Golden Knights>, <NHLGame: 2021-02-05: San Jose Sharks @ Anaheim Ducks>, ....]>

If I want to sort this by the Home team name i can do games.order_by('home_team__team_name') which gives me:如果我想按主队名称对其进行排序,我可以执行games.order_by('home_team__team_name')这给了我:

<QuerySet [<NHLGame: 2021-02-05: San Jose Sharks @ Anaheim Ducks>, <NHLGame: 2021-02-06: San Jose Sharks @ Anaheim Ducks>, <NHLGame: 2021-02-18: Minnesota Wild @ Anaheim Ducks>, <NHLGame: 2021-02-20: Minnesota Wild @ Anaheim Ducks>, <NHLGame: 2021-02-27: Vegas Golden Knights @ Anaheim Ducks>, <NHLGame: 2021-02-12: St. Louis Blues @ Arizona Coyotes>, <NHLGame: 2021-02-13: St. Louis Blues @ Arizona Coyotes>, ....]>

but how can I sort my games by the distance they are from a certain city?但是我怎样才能根据它们与某个城市的距离对我的游戏进行排序呢? Is this possible?这可能吗? One thing I did was:我做的一件事是:

all_teams = NHLTeam.objects.all()
distances = {}
for team in all_teams:
    distance_object = Distance.objects.filter(starting_country=country, starting_province=province, starting_city=city, destination=team)
    distance = distance_object[0].distance
    distances[team.team_name] = float(distance)
sorted_list_of_games = sorted(games, key=lambda game: distances[game.home_team.team_name])

After this sorted_list_of_games is the list of games sorted by distance however it returns a list whereas I need a queryset sorted in that order.在这个 sorted_list_of_games 之后是按距离排序的游戏列表,但是它返回一个列表,而我需要一个按该顺序排序的查询集。 Is this possible?这可能吗?

my_filter = Min('home_team__distance__distance',
                filter=(Q(home_team__distance__starting_country=country) &
                        Q(home_team__distance__starting_province=province) &
                        Q(home_team__distance__starting_city=city)))
sorted_queryset = queryset.annotate(distances=my_filter).order_by(
    "distances" if not is_descending else "-distances")

I ended up solving it with this.我最终解决了这个问题。 The Min should be fine since it should be impossible for it to have more than one distance from a city to a team. Min应该没问题,因为它应该不可能从一个城市到一个团队有超过一个距离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM