Как получить список со связанными постами, разделенный запятыми, из поля "многие-ко-многим"?
Я пытаюсь изучить 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 и т.д., но я не могу разобраться с этим.
Любая помощь будет оценена по достоинству.
Вы были очень близки, последняя итерация вашего шаблона должна быть обновлена до:
{% if projects %}
{% for x in projects %}
{{ x.project_number }} | {{ x.project_name }} | {% for y in x.buildingtypes.all %} {{ y.buildingtype }} {% endfor %}
{% endfor %}
{% endif %}
В нем есть доступ к методу all()
отношения m2m, загружающему значения, которые вы можете итерировать.
если вы хотите прочитать об этом подробнее: https://docs.djangoproject.com/en/5.0/ref/templates/language/#accessing-method-calls