如何在 Django 模板中迭代对象的子项

How to iterate in subitems of a object in a django template

views.py:

from django.views import generic
from .models import Servico


class ServicoView(generic.DetailView):
    model = Servico
    context_object_name = 'servico'
    template_name = 'servico.html'

models.py:

from djongo import models


class PublicoAlvo(models.Model):
    def __str__(self):
        return ''
    alvo1 = models.CharField(max_length = 126)
    alvo2 = models.CharField(max_length = 126, blank = True, default = '')
    class Meta:
        abstract = True

class Servico(models.Model):
    t_id = models.CharField(primary_key = True, unique = True, max_length = 252)
    alvos = models.EmbeddedField(
        model_container = PublicoAlvo
    ) 

urls.py:

from django.urls import path
from . import views


urlpatterns = [
    path('servicos/<slug:pk>/', views.ServicoView.as_view(), name = 'servico')
]

我认为这些是我的 Django 应用程序文件夹中的相关文件。回到问题,我如何迭代将要存储在模板中 servico.alvos 中的值?如果我想显示 t_id,我只需要使用 {{ servico.t_id }} 就可以了。我可以这样写:

<HTML1>
{{ servico.alvos.alvo1 }}
<HTML2>
<HTML1>
{{ servico.alvos.alvo2 }}
<HTML2>

这将显示我想要的值,但会使事情变得更难看,因为我将不得不编写大量重复的标准 HTML(我表示为 and )来格式化 [ 中的每个值=17=],并且更受限制(想象一下,如果我决定更改模型并在 PublicoAlvo class 中添加更多 6 个值)。我尝试了以下方法:

{% for alvo in servico.alvos.all %}
    <HTML1>
    {{ alvo }}
    <HTML2>
{% endfor %}

{% for alvo in servico.alvos.items %}
    <HTML1>
    {{ alvo }}
    <HTML2>
{% endfor %}

但是我什么也没打印出来。当我尝试时:

{% for alvo in servico.alvos %}
    <HTML1>
    {{ alvo }}
    <HTML2>
{% endfor %}

我得到'PublicoAlvo' object is not iterable

有没有办法在我的模板中使用循环或更改我的 models.py 中的内容来获得我想要的内容?

尝试

{{ servico.t_id }}
{{ servico.alvos }}

然后在你的 models.py

class PublicoAlvo(models.Model):
    def __str__(self):
        # Option 1: List all <alvo> fields
        return ", ".join(
            [
                self.alvo1,
                self.alvo2,
            ]
        )

        # Option 2: If you don't like manually listing each <alvo> field
        # return ", ".join(
        #     [
        #         getattr(self, f"alvo{index}") for index in range(1, 3)
        #     ]
        # )

    ...

这可能会给出类似的东西

The value for alvo1, While for alvo2 is this one

更新

你也可以试试

{% for key, value in servico.alvos.items %}
    {% if key|slice:":4" == "alvo" %}
        {{ value }}<br>
    {% endif %}
{% endfor %}

这可能会显示类似

的内容
The value for alvo1
While for alvo2 is this one

根据Niel Godfrey Ponciano的第一个答案,我能够解决问题。

models.py:

from djongo import models


class PublicoAlvo(models.Model):
    def __str__(self):
        return ''
    def list(self):
        return [value for key, value in self.__dict__.items() if not key.startswith('_')] 
    alvo1 = models.CharField(max_length = 126)
    alvo2 = models.CharField(max_length = 126, blank = True, default = '')
    class Meta:
        abstract = True

class Servico(models.Model):
    t_id = models.CharField(primary_key = True, unique = True, max_length = 252)
    alvos = models.EmbeddedField(
        model_container = PublicoAlvo
    ) 

然后我可以在模板中使用 for 迭代 servico.alvos.list,只需添加 list 方法,returns 中的相关字段(变量)值我的 class.