如何从多对多字段获取带逗号分隔的相关帖子列表?

0 投票
1 回答
27 浏览
提问于 2025-04-12 01:32

我正在学习Django,但遇到了一个我怎么也搞不定的问题。在这个项目中,我有一个叫做projects的应用。在这个应用里,我有一个模型叫Projectinfo,还有一个叫Buildingtypes

每个项目可以有一个或多个建筑类型。我想做的是写一个视图,列出所有项目,并把相关的建筑类型用逗号分隔开来显示。

这是我两个模型的简化版本:

class Buildingtypes(models.Model):
    buildingtype = models.CharField(max_length=100)

    def __str__(self):
        return self.buildingtype

class ProjectInfo(models.Model):
    project_number = models.CharField(max_length=12, blank=True)
    project_name = models.CharField(max_length=120)
    buildingtypes = models.ManyToManyField(Buildingtypes, default=[1])

    def __str__(self):
        return self.project_name

我做了一个视图,长这样:

from django.http import HttpResponse
from django.template import loader
from .models import ProjectInfo

def index(request):
    myProjects = ProjectInfo.objects.all()
    template = loader.get_template('projects/index.html')
    context = {
        'projects': myProjects,
        }
    return HttpResponse(template.render(context, request))

还有这个模板:

{% if projects %}
    {% for x in projects %}
        {{ x.project_number }} | {{ x.project_name }} | {{ x.buildingtype }}
    {% endfor %}
{% endif %}

结果是这样的:

projectnumber | project name | building type
----------------------------------------------------------
101010        | project 1    | projects.Buildingtypes.None
202020        | project 2    | projects.Buildingtypes.None

显然这个方法失败了,所以我又试了这个:

{% if projects %}
    {% for x in projects %}
        {{ x.project_number }} | {{ x.project_name }} | {% for y in x.buildingtypes %} {{ y.buildingtype }} {% endfor %}
    {% endfor %}
{% endif %}

结果变成了这样:

projectnumber | project name | building type
----------------------------------------------------------
101010        | project 1    | 
202020        | project 2    | 

我在MySQL里做了一个查询,想给你展示我想要的结果。下面这个查询给了我想要的结果:

SELECT
    project_number,
    project_name,
    GROUP_CONCAT(pb.buildingtype SEPARATOR ', ') AS buildingtypes
FROM
    projects_projectinfo AS pp
JOIN
    projects_projectinfo_buildingtypes AS ppb
ON
    pp.id = ppb.projectinfo_id
JOIN
    projects_buildingtypes AS pb
ON
    ppb.buildingtypes_id = pb.id
GROUP BY
    pp.id;

结果:

projectnumber | project name | building type
--------------------------------------------------------------------------------
101010        | project 1    | building type 1, building type 3
202020        | project 2    | building type 2, building type 5, building type 6

但是,怎么把这个转换成一个视图呢?

我尝试了很多方法,比如select_related、prefetch_related、filter等等,但就是搞不定。

1 个回答

1

你已经很接近了,最后一次更新你的模板需要改成:

{% if projects %}
    {% for x in projects %}
        {{ x.project_number }} | {{ x.project_name }} | {% for y in x.buildingtypes.all %} {{ y.buildingtype }} {% endfor %}
    {% endfor %}
{% endif %}

它确实调用了 m2m 关系的 all() 方法,这样你就可以遍历这些值了。

如果你想了解更多,可以看看这个链接: https://docs.djangoproject.com/en/5.0/ref/templates/language/#accessing-method-calls

撰写回答