ele*_*han 5 python django closures loops django-templates
我在我的网站上的一些页面上有一个评论部分,我用一个{% for ... %}
循环构建(还有另一个用于评论回复的嵌套循环。该部分被黑客攻击在一起,我仍在学习 Web 开发和 Django,所以请原谅任何令人沮丧的草率或怪异. 我现在不关心效率,只关心效率,现在还不太合适。
对于每条评论,我都有一个 Bootstrap 下拉按钮,可以显示选项Edit
和Delete
. Edit
将打开一个模式来编辑评论。模态是用{% include %}
标签呈现的。下面我包含了未修改的部分代码,而不是试图简化我的示例并冒着遗漏一些重要内容的风险:
<div class="panel panel-default">
{% for comment in spot.ordered_comments %}
<div class="panel-heading row">
<div class="col-sm-10">
<strong>{{ comment.poster.username }}</strong>
<em style="margin-left: 2em">{{ comment.created|date:'M d \'y \a\t H:i' }}</em>
</div>
<div class="btn-group col-sm-2" role="group">
{% if comment.poster == user %}
<form id="delete-comment-form" class="form"
method="post" action="{% url 'delete_comment' spot.id comment.id %}">
{% csrf_token %}
</form>
{% include 'topspots/editmodal.html' with edit_type='comment' %}
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-edit"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" data-toggle="modal" data-target="#editModal">Edit</a></li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" onclick="$('#delete-comment-form').submit();">Delete</a>
</li>
</ul>
</div>
{% endif %}
{% if user.is_authenticated %}
{% include 'topspots/replymodal.html' %}
<button type="button" class="btn btn-default" data-toggle="modal"
data-target="#replyModal">
Reply
</button>
{% endif %}
</div>
</div>
<div class="panel-body">
<div class ="row">
<div class="col-sm-8">
{{ comment.comment_text }}
</div>
</div>
<br/>
<!-- Comment replies -->
{% if comment.commentreply_set %}
{% for reply in comment.commentreply_set.all %}
<div class="row" style="padding-left: 1em">
<div class="col-sm-8 well">
<p>{{ reply.reply_text }}</p>
<div class="row">
<div class="col-sm-4">
<p>
<strong>{{ reply.poster.username }}</strong>
<em style="margin-left: 2em">{{ comment.created|date:'M d \'y \a\t H:i' }}</em>
</p>
</div>
{% if reply.poster == user %}
{% include 'topspots/editmodal.html' with edit_type='reply' %}
<form id="delete-reply-form" class="form"
method="post" action="{% url 'delete_reply' spot.id reply.id %}">
{% csrf_token %}
</form>
<div class="col-sm-2">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-edit"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" data-toggle="modal"
data-target="#editModal">Edit</a></li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;"
onclick="$('#delete-reply-form').submit();">Delete</a>
</li>
</ul>
</div>
</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endif %}
</div>
{% endfor %}
</div>
Run Code Online (Sandbox Code Playgroud)
这是编辑模式:
<!-- editmodal.html -->
{% load static %}
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h2 class="modal-title" id="editModalLabel">
Edit {{ edit_type }}:
</h2>
</div>
<form action="{% url 'edit_comment' spot.id comment.id %}" method="post">
<div class="modal-body">
<input class="form-control" name="text" value="{{ comment.comment_text }}" autofocus>
<input type="hidden" name="edit_type" value="{{ edit_type }}">
{% csrf_token %}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-default">Finish editing</button>
</div>
</form>
</div>
</div>
</div>
<script>
$('.modal').on('shown.bs.modal', function() {
$(this).find('[autofocus]').focus();
});
</script>
Run Code Online (Sandbox Code Playgroud)
和回复模式:
<!-- replymodal.html -->
{% load static %}
<div class="modal fade" id="replyModal" tabindex="-1" role="dialog" aria-labelledby="replyModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h2 class="modal-title" id="replyModaLabel">
Reply to <strong>{{ comment.poster.username }}'s</strong> comment
</h2>
</div>
<div class="modal-body">
<form action="{% url 'reply_comment' spot.id comment.id %}" method="post">
<input class="form-control" name="reply_text" placeholder="Write a reply..." autofocus>
{% csrf_token %}
</form>
</div>
</div>
</div>
</div>
<script>
$('.modal').on('shown.bs.modal', function() {
$(this).find('[autofocus]').focus();
});
</script>
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我的回复和编辑模式(例如{% include 'topspots/editmodal.html' with edit_type='reply' %}
或{% include 'topspots/replymodal.html' %}
似乎只在我的 for 循环的第一次迭代的上下文中呈现一次。所以即使所有问题都在页面上正确呈现,当我点击回复时, 编辑或删除,无论我点击哪个按钮(即我是点击第一个评论的按钮,还是第五个评论的按钮等等)我只能回复、编辑或删除第一个评论。我有一个感觉这在某种程度上与闭包和作用域有关,我不太了解(我过去lambda
因为在 Python 循环中使用了意外结果而遇到了麻烦,因为this或this),但我不确定。
我用以下视图进行了测试:
def test(request):
spots = Spot.objects.all()
return render(request, 'test.html', {'spots': spots})
Run Code Online (Sandbox Code Playgroud)
和模板:
<!-- test.html -->
<h1>Hello world</h1>
{% for spot in spots %}
{% include 'testinclude.html' %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
和
<!-- testinclude.html -->
<h3>{{ spot.name }}</h3>
Run Code Online (Sandbox Code Playgroud)
它打印出一个独特的点名称列表,那么为什么与模态不同呢?
正如emulbreh 假设的那样,实际上每个评论都会呈现一个模式。但是,所有模态框都具有相同的 ID,因此无论单击哪个 comment\xe2\x80\x99s 编辑按钮,每次都会触发第一个模态框。ID 在 HTML 文档中应该是唯一的。
\n\n你该如何解决这个问题?您可以使每个评论的模态 ID 都是唯一的。id="editModal-{{ comment.id }}"
您可以通过写入或仅获取唯一标识符id="editModal-{{ forloop.counter }}
(此处的文档)。
但是您的editModal.html
模板与 \xe2\x80\x98master\xe2\x80\x99 模板紧密耦合。更好的解决方案是使用类而不是 ID,并将标识放在它所属的位置:每个评论的容器。你可以试试:
向每个 comment\xe2\x80\x99s 容器添加 ID:
\n\n<div class="panel panel-default">\n{% for comment in spot.ordered_comments %}\n <div class="panel-heading row" id="comment-{{ comment.id }}">\n ...\n
Run Code Online (Sandbox Code Playgroud)在模态模板中使用类而不是 ID,如下所示:
\n\n<!-- editmodal.html -->\n{% load static %}\n\n<div class="modal fade editModal" tabindex="-1" ...>\n ...\n
Run Code Online (Sandbox Code Playgroud)data-target
将按钮更改为:
<li><a href="#" data-toggle="modal" data-target="#editModal">Edit</a></li>\n
Run Code Online (Sandbox Code Playgroud)\n\n到:
\n\n<li><a href="#" data-toggle="modal" data-target="#comment-{{ comment.id }} .editModal">Edit</a></li>\n
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
1520 次 |
最近记录: |