我正在尝试构建一个查询三个表的简单网页。有Company
表与Position
表具有一对多关系,以及与Project
表的一对多关系。
目标是让页面显示一次给定的公司,以及与该公司相关的所有职位和项目。然后,继续展示下一家公司,在那里举行的任何职位和完成的项目。
以下是我最接近这个问题的方法。但是,显而易见的问题是,如果有一个以上的项目与某个公司相关联,您会看到该公司不止一次上市。
我是Django的新手,所以为了学习,我想在寻求帮助之前足够努力地击败自己的脑袋;但此时我真的可以使用一些新鲜的想法。
另外:我可以看到嵌套for循环在这里是如何工作的,但是我不清楚它的机制如何与查询一起工作,然后在模板中。
型号:
from django.db import models
class Company(models.Model):
company_id = models.AutoField(primary_key=True)
company_name = models.CharField(max_length=20)
company_logo = models.ImageField(upload_to='images/')
def __str__(self):
return self.company_name
class Position(models.Model):
position_id = models.AutoField(primary_key=True)
position_title = models.CharField(max_length=55)
company_id = models.ForeignKey('professional.Company',
on_delete=models.CASCADE,
blank=True,
null=True)
begin_date = models.DateField()
end_date = models.DateField()
def __str__(self):
return self.position_title
class Project(models.Model):
project_id = models.AutoField(primary_key=True)
project_name = models.CharField(max_length=55)
company_id = models.ForeignKey('professional.Company',
on_delete=models.CASCADE,
blank=True,
null=True)
project_description = models.CharField(max_length=500)
project_image = models.ImageField(upload_to='images/')
def __str__(self):
return self.project_name
查看:
from django.views.generic import TemplateView, ListView
from professional.models import Company
class ProfessionalHome(TemplateView):
template_name = 'professional/professional_home.html'
class TechnologyListView(ListView):
template_name = 'professional/__technology.html'
context_object_name = 'technology_list'
def get_queryset(self):
return Company.objects.values('company_name','position__position_title', 'project__project_name')
HTML和模板:
{% for job in technology_list %}
<h1>{{job.company_name}}</h1>
<h1>Position: {{job.position__position_title}}</h1>
<h1>project: {{job.project__project_name}}</h1>
{% endfor %}
答案 0 :(得分:1)
如果要迭代公司,那么您应该使用公司模型作为视图的基础,而不是技术。此外,除非您知道自己有充分的理由,否则应该避免使用values
和values_list
。您可以使用prefetch_related()
来减少反向查询的数量。所以:
class TechnologyListView(ListView):
def get_queryset(self):
return Company.objects.all.prefetch_related('project','position')
...
{% for company in company_list %}
<h1>{{company.company_name}}</h1>
{% for position in company.position_set.all %}
<h1>Position: {{ position.position_title }}</h1>
{% endfor %}
{% for project in company.project_set.all %}
<h1>project: {{ project.project_name }}</h1>
{% endfor %}
{% endfor %}
(注意,你应该避免让你的ForeignKey字段名称以&#34; _id&#34;结尾.Django字段指的是整个公司,而不是ID;字段应该只调用company
。无论如何,底层数据库将以_id
为后缀。此外,您不需要在所有字段上使用model_name前缀;从访问它们的对象中可以明显看出它。)
答案 1 :(得分:1)
而不是get_queryset
方法中的值,您可以返回实际的查询集,然后迭代它以构建视图。
def get_queryset(self):
return Company.objects.all()
然后在你的模板中:
{% for job in technology_list %}
<h1>{{job.company_name}}</h1>
{% for position in job.position_set.all() %}
<h1>Position: {{position.position_title}}</h1>
{% endfor %}
{% for project in job.position_set.all() %}
<h1>project: {{project.project_name}}</h1>
{% endfor %}
{% endfor %}