javascript - 如何正确序列化?按下时,Ajax 会更新对象 forloop 中 django upvote 按钮的所有实例
问题描述
好的,所以我有一个索引页面,其中包含可以被赞成或反对的项目。问题是,当我对一项项目进行投票/反对时,页面上的所有项目都被赞成/反对,并且页面上所有按钮的外观都发生了变化,而不仅仅是被赞成/反对的一个对象。
谁能帮我正确序列化每个 for 循环对象?
我的索引页:
{% for post in posts %}
<span id="post_{{forloop.counter}}" data-value="{{post.id}}"></span>
<button class="vote_action" value="upvote_button"> + </i></button>
<span id="votes_{{forloop.counter}}">{{post.points}}</span>
<button class="vote_action" value="downvote_button"> - </button>
{% endfor %}
...
<script type="text/javascript">
// JQUERY - AJAX SCRIPT FOR voting
$(document).ready(function(){
{% for post in posts %}
$('.vote_action').click(function(e) {
var postid = document.getElementById('post_{{forloop.counter}}').getAttribute('data-value');
var button = $(this).attr("value");
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "vote" %}',
data: {
postid: postid,
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'postvote',
button: button,
},
success: function(json){
if (json.length < 1 || json == undefined) {
//empty
}
document.getElementById("votes_{{forloop.counter}}").innerHTML = json['result']
//change button looks
$("#uvb_{{forloop.counter}}").addClass("disabled");
$("#dvb_{{forloop.counter}}").addClass("disabled");
},
error: function(xhr, errmsg, err) {}
})
})
{% endfor %}
})
</script>
我的意见功能:
@login_required
def post_vote(request):
if request.POST.get('action') == 'postvote':
# get information from request about what item id it is
id = int(request.POST.get('postid'))
# And also which button was pressed
button = request.POST.get('button')
post = Posts.objects.get(id=id)
if button == 'downvote_button':
if not post.voters.filter(id=request.user.id).exists():
post.voters.add(request.user)
post.votes +=1
post.points -=2
post.save()
elif button == 'upvote_button':
if not post.voters.filter(id=request.user.id).exists():
post.voters.add(request.user)
post.votes +=1
post.points +=2
post.save()
# return result
post.refresh_from_db()
result = post.points
return JsonResponse({'result':result})
pass
解决方案
除了使用for-loop
for 脚本,您还可以简单地使用jqueryclosest()
的find()
方法来实现相同的目标。以下是您需要在django代码中进行的一些更改:
{% for post in posts %}
<div> //<!--add this div-->
<span id="post_{{forloop.counter}}" data-value="{{post.id}}"></span>
<button class="vote_action" value="upvote_button"> + </i></button>
//<!--add class here-->
<span id="votes_{{forloop.counter}}" class="votes_points">{{post.points}}</span>
<button class="vote_action" value="downvote_button"> - </button>
</div>
{% endfor %}
然后,在您的 jquery 代码中,每当您的按钮被单击时,使用closest()
方法来获取最接近的div
然后使用它找到span
位置class="votes_points"
并获取它id
并使用split
方法来获取值。使用{{forloop.counter}}
它我们也可以轻松地获取postid
值。因此,您的jquery代码将如下所示:
$('.vote_action').click(function(e) {
//get closest div
var selector = $(this).closest('div');
var button = $(this).attr("value");
//find class get id and split to get counter
var counter =selector.find('.votes_points').attr('id').split('_')
//get span data-value
var postid = selector.find("span[id=post_"+counter[1]+"]").attr('data-value');
console.log("postID-->"+postid+"Button-->"+button+"counter[1]-->"+counter[1])
e.preventDefault();
//your ajax
$.ajax({
type: 'POST',
url: '{% url "vote" %}',
data: {
postid: postid,
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'postvote',
button: button
},
success: function(json) {
if (json.length < 1 || json == undefined) {
//empty
}
//add response to votes_point
selector.find('.votes_points').text(json['result'])
//change button looks
$("#uvb_"+counter[1]).addClass("disabled");
$("#dvb_"+counter[1]).addClass("disabled");
},
error: function(xhr, errmsg, err) {}
})
})
演示代码(带演示数据):
$('.vote_action').click(function(e) {
//get closest div
var selector = $(this).closest('div');
var button = $(this).attr("value");
//find class get id and split to get counter
var counter =selector.find('.votes_points').attr('id').split('_')
//get span data-value
var postid = selector.find("span[id=post_"+counter[1]+"]").attr('data-value');
console.log("postID-->"+postid+" || Button-->"+button+" || counter[1]-->"+counter[1])
e.preventDefault();
//your ajax
$.ajax({
type: 'POST',
url: '{% url "vote" %}',
data: {
postid: postid,
csrfmiddlewaretoken: '{{ csrf_token }}',
action: 'postvote',
button: button
},
success: function(json) {
if (json.length < 1 || json == undefined) {
//empty
}
//add response to votes_point
selector.find('.votes_points').text(json['result'])
//change button looks
$("#uvb_"+counter[1]).addClass("disabled");
$("#dvb_"+counter[1]).addClass("disabled");
},
error: function(xhr, errmsg, err) {}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<span id="post_1" data-value="1"></span>
<button class="vote_action" value="upvote_button"> +</button>
<span id="votes_1" class="votes_points">15</span>
<button class="vote_action" value="downvote_button"> - </button>
</div>
<div>
<span id="post_2" data-value="2"></span>
<button class="vote_action" value="upvote_button"> +</button>
<span id="votes_2" class="votes_points">52</span>
<button class="vote_action" value="downvote_button"> - </button>
</div>
<div>
<span id="post_3" data-value="3"></span>
<button class="vote_action" value="upvote_button"> +</button>
<span id="votes_3" class="votes_points">52</span>
<button class="vote_action" value="downvote_button"> - </button>
</div>
推荐阅读
- mysql - 谁能告诉这个mysql代码有什么问题?
- javascript - C# DateTime - 使用 fullcalendar.io 处理时区的最佳方法?
- c# - 在 ASP.NET 中接收查询字符串数组?
- java - 在 EclipseLink 中分离实体
- git - 在团队资源管理器中使用 Git 存储库将现有项目添加到 Visual Studio 2017 解决方案中的源代码管理
- java - POST请求时出现Spring“No 'Access-Control-Allow-Origin' header”错误
- qt - Qt Creator/CMake 不会在编译输出中每秒更新文件
- node.js - 我们应该使用 Async / Await 还是 Then Closures 来避免内存泄漏?
- c# - ASP.NET 显示列表
在 listview 或 gridview 而不是 dropdownlist 中(Web 服务应用程序) - sql - SQL 将日期转换为工作日名称