我想在 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
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 %}
这应该对你有用:
publication = publication.objects.select_related('yourfield', 'yourfield', 'yourfield')
让我首先描述术语的含义并开始排序......
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”(基于哪个对象)匹配的任何一个中的任何一个,这使得它本身成为内联。
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
– 基于我刚刚在项目中经历的内容。
由于您的查询集是通过上下文设置的
dic['plist']
,那么,在模板中您可以:
{% for itero in plist %}
{{ itero.title }}
{{ itero.city.city_name }}
{{ itero.citystate.citystate_name }}
{{ itero.country.country_name }}
{% endfor %}