簡體   English   中英

如何在 Django 中進行內部連接?

[英]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 ,因為您可以在模板中直接遍歷citycountrystatecountry - 基於我剛剛在我的項目中經歷的。

由於您的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM