web-dev-qa-db-ja.com

Djangoで内部結合を作成するには?

出版物の都市、州、および国の名前をHTMLで表示したいと思います。しかし、それらは異なるテーブルにあります。

これが私の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

これが私の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)

Djangoビューでは、次の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

おそらく _select_related_ を探しているでしょう。これはこれを達成するための自然な方法です:

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

結果のSQLはstr(pubs.query)で確認できます。これにより、次の行に沿った出力が得られます(例は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" ) 
_

その後、返されたカーソル値は適切なORMモデルインスタンスに変換されるため、これらのパブリケーションをループするときに、独自のオブジェクトを介して関連テーブルの値にアクセスできます。ただし、事前に選択された前方関係に沿ったこれらのアクセスでは、追加のデータベースヒットは発生しません。

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