如何在django中创建内部连接?

6vl6ewon  于 2021-06-21  发布在  Mysql
关注(0)|答案(4)|浏览(283)

我想在html中显示出版物的城市、州和国家的名称。但他们在不同的table上。
这是我的模特

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

这是我的观点

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
qvtsj1bj

qvtsj1bj1#

你可能在找 select_related ,这是实现这一点的自然方法:

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

您可以通过 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模型示例,以便在循环这些发布时,通过相关表自己的对象访问它们的值。但是,这些沿预选转发关系的访问不会导致额外的db命中:

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

wlwcrazw2#

让我从描述术语的含义开始,然后开始。。。
innerjoin表示两个(或多个)表之间的“common”部分。正如sql查询所建议的那样,每一个都是一个接一个地执行的。
在执行sql查询时,您将publication视为main,所有查询都是publication中的外键,从而提供了整个数据集。
如果我的理解正确的话,那么您在django中寻找的是filter,在chain(而不是query)中,因为q将分别给出每个q的结果,并将它们连接起来,而您希望一个q的结果应用到另一个q上。
(我不知道dic.update({“plist”:mypublications})做什么,不清楚。。解决方案: country = country.objects.all() #把所有的国家都列在国家表上。 country_state = countrystate.objects.all() #获取所有countrystate对象 city = city.objects.all() #获取所有城市对象
解决方案1:在python3中,您需要使用\uu-in,这在python2中可以正常工作。并且会让你的国家与任何东西从表国家(不是没有),表国家(不是没有),表城市(不是没有),所以如果有任何从他们中,它将提供。注意:'none'(python)='null'(sql数据库)获取所有具有上述内容的发布(实际上将为您带来任何内容)。 publications_list = publication.objects.filter(country = country, countrystate = country_state, city = city) #如果“id”(基于哪个是object)匹配的任何对象中有任何人,则获取,这使其本身成为innerjoin。

z8dt9xmd

z8dt9xmd3#

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
w41d8nur

w41d8nur4#

你不需要内在的联结 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 %}

相关问题