Django高级加入/查询,如何过滤外键?

时间:2017-03-01 20:00:02

标签: django join annotations

我有这两种模式。

class City(models.Model):
    city    = models.CharField(max_length=200)
    country = models.CharField(max_length=200)

class CityTranslation(models.Model):
    city    = models.ForeignKey(City)
    name    = models.CharField(max_length=200)
    lang    = models.CharField(max_length=2)
    prio    = models.IntegerField()

每个城市都可以在一种语言中使用多个翻译名称。

所以我希望得到所有城市的国家=“波兰”。如果相应的城市有一个或多个具有lang = name的CityTranslations。我想只获得prio订购的第一个。

我现在正在做类似的事情。

City.objects.filter(country="Poland", citytranslation__land="pl").annotate(transname=F("alt_names__name"))

但这不起作用,因为:

  1. 如果有一个没有CityTranslation的城市,则需要列出
  2. 如果有多个CityTranslation,则会显示所有内容。但我只想要第一个。 (... .ordered_by('prio')。first())
  3. 有什么想法吗?

    编辑: 通过使用@property字段解决了这个问题,该字段按prio命令我的CityTranslation并选择第一个:

    @propert
    def transcity(self):
        return self.citytranslation.filter(lang="pl").order_by('-prio').first()
    

1 个答案:

答案 0 :(得分:0)

def magic(passed_country="Poland", passed_lang="pl")
    # I want to get all City's with country="Poland".
    cities = City.objects.filter(country=passed_country)

    # If a corresponding City has one or more CityTranslations with lang=name. I want to get only the first ordered by prio.
    suitable_cities = cities.filter(citytranslation__lang=passed_lang)
    if suitable_cities.exists()
        first_matching_city = suitable_cities.orderby('prio').first()
    else:
        first_matching_city = cities.orderby('prio').first()

    return first_matching_city

可能需要在citytranslation上设置相关名称。

如果您计划按ID排序,可能不需要订购。