(Django)Ajax - 多个对象

时间:2016-04-04 06:05:23

标签: jquery ajax django

我真的需要一些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}}对象。

我该如何解决这个问题?谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

  1. 您正在循环中创建标识为fav的HTML元素。如果循环有多次迭代,这将导致错误的HTML,其中几个元素具有相同的id。

  2. 您查找$('#fav')而不是触发提交事件的元素。

  3. =&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
}