我真的需要一些Ajax和Django的帮助!我试图遍历所有Item
个对象,以便每个对象都有一个单独的表单,允许用户使用ajax按钮favorite
该项目。
这是我的表格:
<div class="row">
{% for item in items%}
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
{% if item.photo %}
<img src="{{ MEDIA_URL }}{{item.photo.url}}">
{% endif %}
<div class="caption">
<h3>{{item.name}}</h3>
<p>{{item.description}}</p>
<h3>Price: {{item.price}}</h3>
<h3>Rating: {{item.rating}}</h3>
<p>
<form id="add_favorite_form">
{% csrf_token %}
<button id='fav' class='btn btn-primary' type="submit" data-itemid="{{item.id}}" value="Favorite">
Favorite
<span class="glyphicon glyphicon-thumbs-up"</span></a>
</form>
</p>
</div>
</div>
</div>
{% endfor %}
</div>
这是Ajax:
<script type="text/javascript">
$(document).on('submit', '#add_favorite_form',function(e){
e.preventDefault();
var $fav = $('#fav');
$.ajax({
type: "POST",
url: "/items/favorites/",
data: {
id: $($fav).attr('data-itemid'),
csrfmiddlewaretoken:$("input[name=csrfmiddlewaretoken]").val()
},
success: function(){
alert("button works but is broken. Only the first Item instance is added to favorites")
}
});
});
</script>
最后,我的意见:
def favorite_item(request):
favorites, created = Favorite.objects.get_or_create(user=request.user)
if request.method == "POST":
id = request.POST['id']
item = Item.objects.get(id=id)
print item
favorites.items.add(item)
favorites.save()
return HttpResponse(' ')
如您所见,该按钮使用{{item.id}}
作为data-*
属性,因此我假设这会将每个item.id
的值传递给变量var $fav = $('#fav');
在ajax脚本中。但是,似乎只传递了第一个item.id
,因为这是唯一添加到Item
的{{1}}对象。
我该如何解决这个问题?谢谢你的帮助。
答案 0 :(得分:1)
您正在循环中创建标识为fav
的HTML元素。如果循环有多次迭代,这将导致错误的HTML,其中几个元素具有相同的id。
您查找$('#fav')
而不是触发提交事件的元素。
=&GT;从标记中删除id='fav'
。 (如果需要,您可以添加id='fav-{{item.id}}
之类的ID,但不是必需的。
=&GT;改变你的JS:
<script type="text/javascript">
var csrftoken = $("input[name=csrfmiddlewaretoken]").val();
$(document).on('submit', '#add_favorite_form',function(e){
e.preventDefault();
var itemId= $(e.target).data('itemid'); // jquery +1.4.3 or attr()
$.ajax({
type: "POST",
url: "/items/favorites/",
data: {
id: itemId,
csrfmiddlewaretoken: csrftoken
},
success: function(){
alert("Added favorite " + itemId);
}
});
});
</script>
编辑:
更简单的方法是使用表单,只需通过AJAX提交即可。
<form id="add_favorite_{{ item.id }}" class="add_favorite_form" method="POST" action="{% url 'add-favorite' %}">
{% csrf_token %}
<input type="hidden" name="id" value="{{ item.id }}" />
<button id='fav' class='btn btn-primary' type="submit" value="Favorite">
Favorite
<span class="glyphicon glyphicon-thumbs-up"</span></a>
</form>
JS:
<script type="text/javascript">
var csrftoken = $("input[name=csrfmiddlewaretoken]").val();
$(document).on('submit', '.add_favorite_form',function(e) {
e.preventDefault();
e.stopPropagation();
var $form = $(this);
var url = $form.attr( "action" );
var thisId = $form.attr( "id" );
$.post(url, $form.serialize())
.done(function(data) {
alert("Added favorite " + thisId);
});
});
</script>
答案 1 :(得分:0)
你有一些错误,但导致你出现问题的是$('#fav')
只会在页面上找到带有该ID的第一个元素。
您会发现很难调整当前的JavaScript,因为它依赖于页面提交。你可以改变它,让按钮使用onclick事件。
您只需要包含CSRF令牌,但有很多资源可以解决这个问题。
<button onclick="favourite({{item.id}})" class='btn btn-primary' value="Favorite">
function favourite(id){
// Use the id passed to the method
}