web-dev-qa-db-fra.com

Comment créer une jointure interne dans Django?

Je souhaite afficher en Html le nom de la ville, de l'état et du pays d'une publication. Mais ils sont dans des tableaux différents.

Voici mon models.py

class country(models.Model):
    country_name = models.CharField(max_length=200, null=True)
    country_subdomain = models.CharField(max_length=3, null=True)
    def __str__(self):
        return self.country_name

class countrystate(models.Model):
    state_name = models.CharField(max_length=200, null=True)
    country = models.ForeignKey(country, on_delete=models.CASCADE, null=True)
    importance = models.IntegerField(null=True)
    def __str__(self):
        return self.state_name

class city(models.Model):
    city_name = models.CharField(max_length=200, null=True)
    countrystate = models.ForeignKey(countrystate, on_delete=models.CASCADE, null=True)
    def __str__(self):
        return self.city_name

class publication(models.Model):
    user = ForeignKey(users, on_delete=models.CASCADE, null=False)
    title= models.CharField(max_length=300, null=True)
    country=models.ForeignKey(country, on_delete=models.CASCADE, null=True)
    countrystate=models.ForeignKey(countrystate, on_delete=models.CASCADE, null=True)
    city=models.ForeignKey(city, on_delete=models.CASCADE, null=True)

    def __str__(self):
        return self.title

Voici mon views.py

def publications(request):
    mypublications = publication.objects.filter(user_id=request.session['account_id'])
    dic.update({"plist": mypublications })
    return render(request, 'blog/mypublications.html', dic)

Dans une vue Django, quel est l'équivalent de la prochaine requête SQL?

SELECT p.user_id, p.title, c.cuntry_id, c.country_name, s.state_id, s.state_name, y.city_id, y.city_name FROM publication AS p
INNER JOIN country AS c ON c.id = p.country_id
INNER JOIN countrystate AS s ON s.id = p.countrystate_id
INNER JOIN city AS y ON y.id = p.city_id
8
Sergio Mendez

Vous recherchez probablement select_related , qui est le moyen naturel d'y parvenir:

pubs = publication.objects.select_related('country', 'country_state', 'city')

Vous pouvez vérifier le SQL résultant via str(pubs.query), ce qui devrait entraîner une sortie sur les lignes suivantes (l'exemple provient d'un backend postgres):

SELECT "publication"."id", "publication"."title", ..., "country"."country_name", ...  
FROM "publication" 
INNER JOIN "country" ON ( "publication"."country_id" = "country"."id" ) 
INNER JOIN "countrystate" ON ( "publication"."countrystate_id" = "countrystate"."id" ) 
INNER JOIN "city" ON ( "publication"."city_id" = "city"."id" ) 

Les valeurs de curseur renvoyées sont ensuite traduites dans les instances de modèle ORM appropriées, de sorte que lorsque vous parcourez ces publications, vous accédez aux valeurs des tables associées via leurs propres objets. Cependant, ces accès le long des relations directes présélectionnées ne provoqueront pas de hits db supplémentaires:

{% for p in pubs %}
     {{ p.city.city_name}}  # p.city has been populated in the initial query
     # ...
{% endfor %}
17
schwobaseggl