如何在 django 中进行内连接?

问题描述 投票:0回答:5

我想在 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)

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)

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

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)

这是我的观点.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
mysql django django-queryset inner-join
5个回答
56
投票

您可能正在寻找

select_related
,这是实现此目的的自然方法:

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

您可以通过

str(pubs.query)
检查生成的 SQL,这应该会产生如下所示的输出(示例来自 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 %}

5
投票

这应该对你有用:

publication = publication.objects.select_related('yourfield', 'yourfield', 'yourfield')

3
投票

让我首先描述术语的含义并开始排序......

InnerJoin 意味着两个(或多个)表之间的“公共”部分。正如您的 SQL 查询所示,每一项都被一个接一个地执行。

通过 SQL 查询,您将出版物视为主要内容,您的所有查询都是出版物中的外键,为您提供整个数据集。

如果我的理解正确的话,你在 Django 中寻找的等效项是链式过滤器(而不是查询),因为 Q 会分别为你提供每个 Q 的结果并将它们连接起来,而你希望将一个结果应用于另一个。

(我不知道 dic.update({"plist": mypublications }) 的作用是什么,不清楚.. 解决方案:

country = country.objects.all()
# 获取国家表中的所有国家。
country_state = countrystate.objects.all()
# 获取所有国家对象
city = city.objects.all()
# 获取所有城市对象

解决方案1:在python3中你需要使用__in,这在Python2中可以正常工作。并且将为您提供国家/地区表国家/地区(不是无)、表国家/地区(不是无)、表城市(不是无)中的任何内容,因此,如果来自其中任何一个,它都会提供。 注意:“无”(python) =“空”(SQL 数据库) 获取所有包含上述内容的出版物(实际上会给你带来任何东西。

publications_list = publication.objects.filter(country = country, countrystate = country_state, city = city)
# 获取“id”(基于哪个对象)匹配的任何一个中的任何一个,这使得它本身成为内联。


-1
投票
from django.db import models

class Course(models.Model):
    name=models.CharField(max_length=10)
    courseid=models.CharField(max_length=30,primary_key=True)
class Enrollment(models.Model):
    course=models.ForeignKey(Course,on_delete=models.CASCADE)
    enrollid=models.CharField(max_length=20)

#Queryset:
k=Enrollment.objects.filter(course__courseid=1).values('id','course__courseid','course__name','enrollid')

print(k.query)
SELECT "app1_enrollment"."id", "app1_enrollment"."course_id", "app1_course"."name", "app1_enrollment"."enrollid" FROM "app1_enrollment" INNER JOIN "app1_course" ON ("app1_enrollment"."course_id" = "app1_course"."courseid") WHERE "app1_enrollment"."course_id" = 1

-2
投票

对于这个简单的情况,您不需要 INNER JOIN 也不需要

select_related
,因为您可以在模板中直接遍历到
city
countrystate
country
– 基于我刚刚在项目中经历的内容。

由于您的查询集是通过上下文设置的

dic['plist']
,那么,在模板中您可以:

{% for itero in plist %}

{{ itero.title }}
{{ itero.city.city_name }}
{{ itero.citystate.citystate_name }}
{{ itero.country.country_name }}

{% endfor %}
© www.soinside.com 2019 - 2024. All rights reserved.