如何在django中进行内部加入?

Ser*_*dez 8 python mysql django orm inner-join

我想在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
Run Code Online (Sandbox Code Playgroud)

这是我的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)
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

sch*_*ggl 17

您可能正在寻找select_related实现这一目标的自然方式:

pubs = publication.objects.select_related('country', 'country_state', 'city')
Run Code Online (Sandbox Code Playgroud)

您可以检查生成的SQL via 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" ) 
Run Code Online (Sandbox Code Playgroud)

然后,返回的游标值将转换为相应的ORM模型实例,以便在循环遍历这些发布时,可以通过自己的对象访问相关表的值.但是,沿预先选择的前向关系的这些访问不会导致额外的db命中:

{% for p in pubs %}
     {{ p.city.city_name}}  # p.city has been populated in the initial query
     # ...
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

  • 反向关系怎么样? (6认同)

小智 5

这应该对你有用:

publication = publication.objects.select_related('yourfield', 'yourfield', 'yourfield')
Run Code Online (Sandbox Code Playgroud)