如何在 Django 模板中将对我的 for 循环的响应数量限制为 3?
How to limit the number of responses to my for loop to 3 in Django Templates?
在我当前的 Django 模板中,我使用了两个模型,它们在我的 views.py 中定义为:
'tasks' : IndividualTask.objects.all(),
'updates' : TaskUpdate.objects.all(),
我已经设置了信号,以便在有任务更新时创建更新。
目前,我遍历每个任务,然后是它们的每个更新,并为每个任务提取相关更新,如下所示。
{% for task in tasks %}
{% for update in updates %}
{% if task.id == update.task.id %}
{{ update.update }}
{% endif %}
{% endfor %}
{% endfor %}
但是,我想将显示的更新数量限制为三个。
我尝试使用切片,如下所示,但这将所有更新限制在所有更新的前 3 个,而不是每个单独任务更新的前 3 个。
{% for task in tasks %}
{% for update in updates|slice:":3" %}
{% if task.id == update.task.id %}
{{ update.update }}
{% endif %}
{% endfor %}
{% endfor %}
Models.py如下:
class IndividualTask(models.Model):
task = models.CharField(
max_length = 256,
blank=False,
null=True,
)
task_description = models.CharField(
max_length = 256,
blank=False,
null=True,
)
expected_completion = models.DateField(
max_length = 64,
null=True,
)
goal = models.ForeignKey(
IndividualGoal,
on_delete=models.CASCADE,
related_name="goals",
blank=False,
null=True,
)
creator = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="creator",
blank=False,
null=True,
)
owner = models.ForeignKey(
User,
on_delete=models.CASCADE,
blank=False,
null=True,
)
status_choices = [
("", "Select Current Status"),
("Preparation", "Preparation"),
("Review", "Review"),
("Update", "Update"),
("Finalised", "Finalised"),
]
current_status = models.CharField(
max_length=32,
choices = status_choices,
default = "Select current status",
)
created = models.DateField(
auto_now_add = True,
)
def __str__(self):
return f"{self.task}"
class TaskUpdate(models.Model):
update = models.CharField(
max_length = 5000,
)
task = models.ForeignKey(
IndividualTask,
on_delete=models.CASCADE,
null = True,
)
update_created = models.DateField(
auto_now_add = True,
)
update_time_created = models.TimeField(
auto_now_add = True,
)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="update_author",
blank=True,
null=True,
)
update_choices = [
("New Task", "New Task"),
("New Commentary", "New Commentary"),
]
update_status = models.CharField(
max_length=32,
choices = update_choices,
null = True,
)
class Meta:
ordering = ["-update_created", "-update_time_created"]
请教我如何将每个任务显示的更新数量限制为 3 个,如果有任何建议,我将不胜感激?
编辑:
完整的追溯如下所示:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/tasks/
Django Version: 4.0.2
Python Version: 3.9.10
Installed Applications:
['tasks.apps.TasksConfig',
'notes',
'accounts',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template /Users/Tom/Desktop/squeasy/tasks/templates/tasks/tasks.html, error at line 69
'RelatedManager' object is not iterable
59 : Expected Completion Date
60 : </div>
61 : <div class = expected_completion>
62 : {{ task.expected_completion }}
63 : </div>
64 : </div>
65 : </div>
66 : <div class = task_sub_header>
67 : Latest updates:
68 : </div>
69 : {% for update in task.taskupdate_set|slice:":3" %}
70 : {% if task.id == update.task.id %}
71 : <div class = individual_update>
72 : {% if update.update_status == "New Task" %}
73 : {{ update.author }} created this task on {{ update.update_created|date:"l jS F" }} at {{ update.update_time_created|time:"H:i" }}
74 : {% elif update.update_status == "New Commentary" %}
75 : {{ update.author }} updated the commentary for {{ update.task }} on {{ update.update_created|date:"l jS F" }} at {{ update.update_time_created|time:"H:i" }}
76 : {% endif %}
77 : </div>
78 : {% endif %}
79 : {% endfor %}
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/Tom/Desktop/squeasy/tasks/views.py", line 28, in tasks
return render(request, "tasks/tasks.html", context)
File "/usr/local/lib/python3.9/site-packages/django/shortcuts.py", line 19, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "/usr/local/lib/python3.9/site-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
File "/usr/local/lib/python3.9/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 176, in render
return self._render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 168, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/loader_tags.py", line 153, in render
return compiled_parent._render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 168, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/loader_tags.py", line 65, in render
result = block.nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 298, in render
return nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 217, in render
nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 217, in render
nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 298, in render
return nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 173, in render
values = list(values)
Exception Type: TypeError at /tasks/
Exception Value: 'RelatedManager' object is not iterable
在上下文中,您可以传递 IndividualTask
s 和 TaskUpdate
s 按降序排列 Prefetch
object [Django-doc]:
from django.db.models import Prefetch
context = {
'tasks' : IndividualTask.objects.prefetch_related(
<strong>Prefetch(</strong>'taskupdate_set', TaskUpdate.objects<strong>.order_by('-update_created', '-update_time_created'))</strong>
)
}
然后在模板中枚举 taskupdate_set
:
{% for task in tasks %}
{% for update in task.taskupdate_set.all|slice:":3" %}
{{ update.update }}
{% endfor %}
{%endfor %}
Note: It is normally better to make use of the settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use the User
model [Django-doc] directly. For more information you can see the referencing the User
model section of the documentation.
在我当前的 Django 模板中,我使用了两个模型,它们在我的 views.py 中定义为:
'tasks' : IndividualTask.objects.all(),
'updates' : TaskUpdate.objects.all(),
我已经设置了信号,以便在有任务更新时创建更新。
目前,我遍历每个任务,然后是它们的每个更新,并为每个任务提取相关更新,如下所示。
{% for task in tasks %}
{% for update in updates %}
{% if task.id == update.task.id %}
{{ update.update }}
{% endif %}
{% endfor %}
{% endfor %}
但是,我想将显示的更新数量限制为三个。
我尝试使用切片,如下所示,但这将所有更新限制在所有更新的前 3 个,而不是每个单独任务更新的前 3 个。
{% for task in tasks %}
{% for update in updates|slice:":3" %}
{% if task.id == update.task.id %}
{{ update.update }}
{% endif %}
{% endfor %}
{% endfor %}
Models.py如下:
class IndividualTask(models.Model):
task = models.CharField(
max_length = 256,
blank=False,
null=True,
)
task_description = models.CharField(
max_length = 256,
blank=False,
null=True,
)
expected_completion = models.DateField(
max_length = 64,
null=True,
)
goal = models.ForeignKey(
IndividualGoal,
on_delete=models.CASCADE,
related_name="goals",
blank=False,
null=True,
)
creator = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="creator",
blank=False,
null=True,
)
owner = models.ForeignKey(
User,
on_delete=models.CASCADE,
blank=False,
null=True,
)
status_choices = [
("", "Select Current Status"),
("Preparation", "Preparation"),
("Review", "Review"),
("Update", "Update"),
("Finalised", "Finalised"),
]
current_status = models.CharField(
max_length=32,
choices = status_choices,
default = "Select current status",
)
created = models.DateField(
auto_now_add = True,
)
def __str__(self):
return f"{self.task}"
class TaskUpdate(models.Model):
update = models.CharField(
max_length = 5000,
)
task = models.ForeignKey(
IndividualTask,
on_delete=models.CASCADE,
null = True,
)
update_created = models.DateField(
auto_now_add = True,
)
update_time_created = models.TimeField(
auto_now_add = True,
)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="update_author",
blank=True,
null=True,
)
update_choices = [
("New Task", "New Task"),
("New Commentary", "New Commentary"),
]
update_status = models.CharField(
max_length=32,
choices = update_choices,
null = True,
)
class Meta:
ordering = ["-update_created", "-update_time_created"]
请教我如何将每个任务显示的更新数量限制为 3 个,如果有任何建议,我将不胜感激?
编辑:
完整的追溯如下所示:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/tasks/
Django Version: 4.0.2
Python Version: 3.9.10
Installed Applications:
['tasks.apps.TasksConfig',
'notes',
'accounts',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template /Users/Tom/Desktop/squeasy/tasks/templates/tasks/tasks.html, error at line 69
'RelatedManager' object is not iterable
59 : Expected Completion Date
60 : </div>
61 : <div class = expected_completion>
62 : {{ task.expected_completion }}
63 : </div>
64 : </div>
65 : </div>
66 : <div class = task_sub_header>
67 : Latest updates:
68 : </div>
69 : {% for update in task.taskupdate_set|slice:":3" %}
70 : {% if task.id == update.task.id %}
71 : <div class = individual_update>
72 : {% if update.update_status == "New Task" %}
73 : {{ update.author }} created this task on {{ update.update_created|date:"l jS F" }} at {{ update.update_time_created|time:"H:i" }}
74 : {% elif update.update_status == "New Commentary" %}
75 : {{ update.author }} updated the commentary for {{ update.task }} on {{ update.update_created|date:"l jS F" }} at {{ update.update_time_created|time:"H:i" }}
76 : {% endif %}
77 : </div>
78 : {% endif %}
79 : {% endfor %}
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/Tom/Desktop/squeasy/tasks/views.py", line 28, in tasks
return render(request, "tasks/tasks.html", context)
File "/usr/local/lib/python3.9/site-packages/django/shortcuts.py", line 19, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "/usr/local/lib/python3.9/site-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
File "/usr/local/lib/python3.9/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 176, in render
return self._render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 168, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/loader_tags.py", line 153, in render
return compiled_parent._render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 168, in _render
return self.nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/loader_tags.py", line 65, in render
result = block.nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 298, in render
return nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 217, in render
nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 217, in render
nodelist.append(node.render_annotated(context))
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 298, in render
return nodelist.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 977, in render
return SafeString(''.join([
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 978, in <listcomp>
node.render_annotated(context) for node in self
File "/usr/local/lib/python3.9/site-packages/django/template/base.py", line 938, in render_annotated
return self.render(context)
File "/usr/local/lib/python3.9/site-packages/django/template/defaulttags.py", line 173, in render
values = list(values)
Exception Type: TypeError at /tasks/
Exception Value: 'RelatedManager' object is not iterable
在上下文中,您可以传递 IndividualTask
s 和 TaskUpdate
s 按降序排列 Prefetch
object [Django-doc]:
from django.db.models import Prefetch
context = {
'tasks' : IndividualTask.objects.prefetch_related(
<strong>Prefetch(</strong>'taskupdate_set', TaskUpdate.objects<strong>.order_by('-update_created', '-update_time_created'))</strong>
)
}
然后在模板中枚举 taskupdate_set
:
{% for task in tasks %} {% for update in task.taskupdate_set.all|slice:":3" %} {{ update.update }} {% endfor %} {%endfor %}
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.