[英]How to make an Inner Join in 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
您可能正在尋找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 模型實例,以便當您循環這些發布時,您可以通過它們自己的對象訪問相關表的值。 但是,這些沿預選前向關系的訪問不會導致額外的 db 命中:
{% for p in pubs %}
{{ p.city.city_name}} # p.city has been populated in the initial query
# ...
{% endfor %}
讓我從描述術語的含義開始,然后開始……
InnerJoin 意味着兩個(或多個)表之間的“公共”部分。 正如您的 SQL 查詢所建議的那樣,一個接一個地執行。
通過 SQL 查詢,您將發布視為主要內容,所有查詢都是發布中的外鍵,為您提供整個數據集。
如果我的理解正確的話,你在 Django 中尋找的等價物是 filter,in chain(而不是 Query),因為 Q 會分別為你提供每個 Q 的結果並將它們連接起來,而你希望將一個結果應用到另一個。
(我不知道 dic.update({"plist": mypublications }) 是做什么的,不清楚.. 解決方案: country = country.objects.all()
# 獲取 country 表中的所有國家。 country_state = countrystate.objects.all()
# 獲取所有國家對象city = city.objects.all()
# 獲取所有城市對象
解決方案1:在python3中您需要使用__in,這在Python2中可以正常工作。 並將為您提供任何來自表國家(不是無),表國家(不是無),表城市(不是無)的國家,所以如果他們中的任何人有任何東西,它都會提供。 注意:'None' (python) = 'Null' (SQL Database) 獲取所有具有上述任何內容的publications_list = publication.objects.filter(country = country, countrystate = country_state, city = city)
(實際上會給你帶來任何東西publications_list = publication.objects.filter(country = country, countrystate = country_state, city = city)
# 獲取是否有任何 'id'(基於對象)匹配的人,這使得它本身成為內部連接。
這應該對您有用:
publication = publication.objects.select_related('yourfield', 'yourfield', 'yourfield')
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
對於這個簡單的案例,您不需要 INNER JOIN 或select_related
,因為您可以在模板中直接遍歷city
、 countrystate
和country
- 基於我剛剛在我的項目中經歷的。
由於您的 QuerySet 是通過上下文dic['plist']
,因此,在模板中,您可以:
{% for itero in plist %}
{{ itero.title }}
{{ itero.city.city_name }}
{{ itero.citystate.citystate_name }}
{{ itero.country.country_name }}
{% endfor %}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.