Как выполнить итерацию в подпунктах объекта в шаблоне django
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')
]
I think these are the relevant files in my Django app folder. Back to the question, how can I iterate over the values that are going to be stored in servico.alvos
in my template? If I want to show t_id
, I just use {{ servico.t_id }}
and it works fine. I could write something like:
{{ servico.alvos.alvo1 }}
{{ servico.alvos.alvo2 }}
И это покажет значения, которые я хочу, но это сделает все более уродливым и ограниченным (представьте, если я решу изменить модель и добавить больше 6 значений в класс PublicoAlvo). Я попробовал следующее:
{% for alvo in servico.alvos.all %}
{{ alvo }}
{% endfor %}
и
{% for alvo in servico.alvos.items %}
{{ alvo }}
{% endfor %}
Но у меня ничего не печатается. Когда я пытаюсь:
{% for alvo in servico.alvos %}
{{ alvo }}
{% 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
Update
Вы также можете попробовать
{% 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
Основываясь на первом ответе Ниэля Годфри Понсиано, я смог решить задачу.
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
)
А затем я могу перебирать servico.alvos.list
, используя for
в шаблоне, просто добавив метод list
, возвращающий значения соответствующих полей (переменных) в моем классе.