gpt4 book ai didi

python - 有没有一种优雅的方式来建模和表示 Django 上多对多关系中的一对多?

转载 作者:太空宇宙 更新时间:2023-11-03 15:20:45 24 4
gpt4 key购买 nike

我有点被一些看起来不太复杂的东西挡住了。这是我的模型:

class Team(models.Model):
name = models.CharField('team name', max_length=200, unique=True)

class QualityStream(models.Model):
name = models.CharField('quality stream name', max_length=200, unique=True)
team = models.ManyToManyField(Team)

class Milestone(models.Model):
name = models.CharField('milestone name', max_length=200)
quality_stream = models.ForeignKey(QualityStream)
team = models.ForeignKey(Team)

如您所见,一个团队可以有几个预定义的质量流,以及几个真正属于质量流的要实现的里程碑。

这是我的看法:

<p>{{team.name}}</p>

{% for stream in team.qualitystream_set.all %}
<p>{{stream.name}}</p>
{% for milestone in team.milestone_set.all %}

{% if milestone.quality_stream.id == stream.id %}
<p>{{milestone.name}}</p>
{% endif %}

{% endfor %}
{% endfor %}

想法是显示团队、与团队相关的质量流以及按质量流分组的每个里程碑:

Team

Quality Stream 1
Milestone 1 for Quality Stream 1
Milestone 2 for Quality Stream 1
Quality Stream 2
Milestone 1 for Quality Stream 2
Milestone 2 for Quality Stream 2

代码运行良好,但我对循环遍历每个质量流的所有里程碑感到不太舒服。我想必须有更好的方法来实现这一目标。有什么想法吗?

最佳答案

每当您认为必须像以前那样执行多个下降循环时,请考虑是否可以从另一端解决问题。

正如@Pathetique 所指出的,以下链接显示了如何最大限度地减少您执行的查询数量:

https://docs.djangoproject.com/en/1.5/topics/db/optimization/#retrieve-everything-at-once-if-you-know-you-will-need-it

该链接中的亮点是 select_related 仅适用于 ForeignKeys,以及 prefetch_related 仅适用于 ManyToManyFields.

由于您是从“我有一组团队,现在我想显示与这些团队相关的所有数据”的角度来处理这个问题的,因此您无法使用自 团队 没有ForeignKeysManyToManyFields

相反,您可以像这样处理问题“我想显示所有里程碑,按团队分组,然后按质量流分组”。由于您的 Milestone 类可以访问您需要的所有数据,因此它使查询集的构造变得非常容易,只需生成一个查询。

def my_view(request):
queryset = Milestone.objects.select_related(
'team', 'quality_stream'
).order_by(
'team__name', 'quality_stream__name'
) # a single query to fetch all teams + streams + milestones

return render_to_response('/your/template.html',
{ 'milestones':queryset },
context_instance=RequestContext(request)
)

现在,您的模板将打破您构建它的方式。这就是我之前提到的问题的定义所在。你有所有的里程碑,但你想按团队然后按质量流对它们进行分组。查询集的排序现在对我们有帮助,因为我们可以遍历所有里程碑,并检查我们是否适合新团队或新质量流。

# your template
{% for milestone in milestones %}
{% ifchanged %} <p> {{ milestone.team.name }} </p> {% endifchanged %}
{% ifchanged %} <p> {{ milestone.quality_stream.name }} </p> {% endifchanged %}
<p> {{ milestone.name }} </p>
{% endfor %}

上面的模板使用了ifchanged模板标签,似乎正是为此目的而设计的。

关于python - 有没有一种优雅的方式来建模和表示 Django 上多对多关系中的一对多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15453840/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com