Django 需要使用Select_related()查询集中的数据的帮助吗
我正在开发一个零件数据库,其中每个零件号也可以是一个部件,这意味着它由任意数量的其他零件组成(循环可以继续,子零件由更多零件组成,等等)。因此,有两个数据库表,一个用于零件信息,另一个用于关系信息——一个与“子部分”编号关联的零件编号。请记住,“组件”、“零件”和“子零件”最终都只是“零件”(有点让人困惑,但它允许一个更加干练和通用的数据库) 我目前正在使用select_相关调用来跟踪模型中使用的ForeignKeys。但是,由于我的查询可能返回的结果不止一个(如果有多个子部分),因此我无法使用“get”查找,而是使用“filter”。因此-我无法跟踪文档中显示的所有基于get查询的示例 与select_相关的查询似乎抓住了我希望它抓住的东西(基于DjangoDebugToolbar显示的原始SQL查询).但是,我不知道如何调用它!显示相关表中的值的正确语法或方法是什么?如何循环返回的queryset中的每个实例?下面的模板片段应该最有效地显示我试图获得的结果。谢谢Django 需要使用Select_related()查询集中的数据的帮助吗,django,django-models,django-select-related,Django,Django Models,Django Select Related,我正在开发一个零件数据库,其中每个零件号也可以是一个部件,这意味着它由任意数量的其他零件组成(循环可以继续,子零件由更多零件组成,等等)。因此,有两个数据库表,一个用于零件信息,另一个用于关系信息——一个与“子部分”编号关联的零件编号。请记住,“组件”、“零件”和“子零件”最终都只是“零件”(有点让人困惑,但它允许一个更加干练和通用的数据库) 我目前正在使用select_相关调用来跟踪模型中使用的ForeignKeys。但是,由于我的查询可能返回的结果不止一个(如果有多个子部分),因此我无法使用
#----------------
#MODEL SNIPPET
#----------------
class Part(models.Model):
ISC_CHOICES = ( #intentionaly removed for this question
)
part_no = models.CharField(max_length=15, primary_key=True)
description = models.CharField(max_length=40, blank=True, null=True)
isc = models.CharField(max_length=2, choices=ISC_CHOICES)
rev = models.CharField(max_length=2, blank=True, null=True)
#this table relates subparts to the part model above- basically is a manual many-to-many field
class PartAssembly(models.Model):
id = models.AutoField(primary_key=True)
part_no = models.ForeignKey(Part, related_name="partno_set")
subpart = models.ForeignKey(Part, related_name="subpart_set")
qty = models.IntegerField(max_length=3)
item_no = models.IntegerField(max_length=3)
#----------------
#VIEW SNIPPET
#----------------
def assembly_details(request, assembly_no): #assembly_no passed through URL
context_instance=RequestContext(request)
subpart_list = PartAssembly.objects.filter(part_no=assembly_no).select_related()
return render_to_response('assembly_details.html', locals(), context_instance,)
#-------------------
# TEMPLATE SNIPPET
#-------------------
{% for partassembly in subpart_list %}
# obviously, this loop doesnt return anything for my part.foo variables below
# it does work for the partassembly.bar
<tr>
<td>{{ partassembly.item_no }}</td> #EDIT: comments are correct
<td>{{ partassembly.subpart }}</td> #partassembly.subpart.part_no
<td>{{ part.description }}</td> #partassembly.subpart.description
<td>{{ part.rev }}</td> #partassembly.subpart.rev
<td>{{ partassembly.qty }}</td>
<td>{{ part.isc }}</td> #partassembly.subpart.isc
</tr>
#----------------
#模型片段
#----------------
类零件(models.Model):
ISC#U CHOICES=(#有意删除此问题)
)
part_no=models.CharField(最大长度=15,主键=True)
description=models.CharField(最大长度=40,空白=True,空=True)
isc=models.CharField(最大长度=2,选项=isc\u选项)
rev=models.CharField(最大长度=2,空白=True,空=True)
#此表涉及上述零件模型的子部分-基本上是一个手动多对多字段
类零件装配(models.Model):
id=models.AutoField(主键=True)
零件号=型号。外键(零件,相关的零件名=“零件号集”)
子部分=型号。外键(相关零件
数量=型号。整型字段(最大长度=3)
项目编号=型号。整数字段(最大长度=3)
#----------------
#查看代码段
#----------------
def程序集详细信息(请求、程序集编号):#通过URL传递的程序集编号
context\u instance=RequestContext(请求)
子部分\u列表=零件装配。对象。过滤器(零件号=装配号)。选择相关()
返回render\u to\u响应('assembly\u details.html',locals(),context\u实例,)
#-------------------
#模板片段
#-------------------
{子部分_列表%中的零件组件的百分比}
#显然,这个循环不会为下面的part.foo变量返回任何内容
#它适用于partassembly.bar
{{partassembly.item_no}}#编辑:注释正确
{{partassembly.subsection}}#partassembly.subsection.part_编号
{{part.description}}#partassembly.subsection.description
{{part.rev}}#partassembly.subsection.rev
{{partassembly.qty}
{{part.isc}}#partassembly.subsection.isc
谢谢你的帮助,我不知道你的麻烦到底出在哪里。记住
选择相关的()
不会以任何方式更改相关实例的对象访问权限-它所做的只是预缓存它们。因此,您引用partassembly.part\u no.rev
等等,就像您没有使用select\u related
一样,所有select\u related
都急切地获取其中声明为ForeignKey
的字段你的模型。它试图避免额外的数据库调用,它不会神奇地让你访问额外的字段
在您的示例中,这意味着访问partassembly.subsection
不会导致额外的数据库选择,因为它是通过调用partassembly.objects.filter()获取的
您的数据模型似乎不正确,但我们将在一分钟内讨论这个问题。首先,我将向您展示如何使用当前数据模型访问所有信息
{% for partassembly in subpart_list %}
<tr>
<td>{{ partassembly.item_no }}</td>
{% for subpart in partassembly.subpart.subpart_set %} # database hit
<td>{{ subpart.subpart }}</td>
<td>{{ subpart.subpart.description }}</td> # database hit
<td>{{ subpart.subpart.rev }}</td>
<td>{{ subpart.qty }}</td>
<td>{{ subpart.subpart.isc }}</td>
{% endfor %}
</tr>
这是因为3mm螺钉(或任何零件)的单个实例在所有部件之间共享。您根本没有真正复制多个表。您的数据模型表示单个零件可以在多个部件中使用
我想你真正想说的是,一个组件可以是另一个组件的一部分,每个组件都是与其结构相关联的多个部分
class Assembly(models.Model):
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
parts = models.ManyToManyField(Part)
name = models.CharField(max_length=..)
现在,当您想要制作椅子时,您可以执行以下操作:
assembly = Assembly.objects.get(name='Chair')
children = assembly.children.all()
print assembly
for part in assembly.parts:
print part
# now you iterate over the tree of children, printing their parts as you go
因此,您的装配模型现在已转换为其他装配的树结构,每个装配都包含自己的零件集。现在您可以识别这是一个树结构,您可以研究如何在Django内的数据库中表示此结构
幸运的是,有一个库可以做到这一点。它可以帮助您表示树结构。它提供了迭代整个树并描述模板中每一棵树的方法
我知道我可能帮助你做了比你认为需要的更多的工作,但我认为这将真正帮助你
祝你好运。这就是答案!不幸的是,我往往在一天结束时在这里发布,当时我自己还没弄清楚,但我所有的文件都还在工作,我无法在家里试用!哈哈。谢谢你的帮助,我会检查出来,可能会在早上接受。我故意远离Differia从子组件到顶部组件从零件等。此应用程序的使用方式要求在任何给定的时间调用特定的子组件,并且不同组件的零件将不一致地位于同一层。我将查看mptt库。可能当我的模型无法正常工作时,我将不可避免地返回此帖子。Th(目前)是一个研发型项目,所以我不太害怕摔在脸上,不得不尝试新的东西(阅读:没有截止日期!)谢谢
assembly = Assembly.objects.get(name='Chair')
children = assembly.children.all()
print assembly
for part in assembly.parts:
print part
# now you iterate over the tree of children, printing their parts as you go