2017-03-01 4 views
-1

Ich habe diese zwei Modelle.Django erweiterte Join/Abfrage, wie Fremdschlüssel zu filtern?

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

Jede Stadt kann mehrere übersetzte Namen in einer Sprache enthalten.

Also ich möchte alle Stadt mit country = "Polen" bekommen. Wenn eine entsprechende Stadt eine oder mehrere CityTranslations mit lang = name hat. Ich möchte nur die erste Bestellung von prio bekommen.

Ich mache jetzt so etwas.

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

Aber das ist nicht funktioniert, weil:

  1. Wenn es eine Stadt ohne CityTranslation es
  2. aufgeführt werden möchten Wenn mehrere CityTranslation die sie sind alle gezeigt werden. Aber ich will nur das erste. (... .ordered_by ('prio'). zuerst())

Irgendeine Idee?

EDIT: es wurde gelöst, indem ein @property Feld verwenden, die meine CityTranslation von PRIO Bestellung und nimmt die erste:

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

Antwort

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 

benötigen eine relatedname auf citytranslation einzurichten.

Möglicherweise brauchen Sie orderby nicht, wenn Sie nach ID sowieso bestellen möchten.