使用Django和jQuery Ajax保存模型排序顺序

4
我正在尝试使用jQuery UI Sortable实现Django模型实例的排序sorting of Django model instances using jQuery UI Sortable。当我拖放图像时,客户端排序操作有效,但排序顺序不会保存到数据库中。在拖放图像后,我在控制台中得到以下记录:"POST /versions/1/sort/ HTTP/1.1" 200 0,因此请求似乎没有问题。更新:这是使用this debugging technique记录在控制台中的请求示例。
"POST /versions/1/sort/ HTTP/1.1" 200 0
format=2013-10-23 11:22:39,604 - django.db.backends - DEBUG - (0.000) SELECT "versions_image"."id", "versions_image"."version_id", "versions_image"."image_text", "versions_image"."status", "versions_image"."order" FROM "versions_image" WHERE "versions_image"."id" = 3 ; args=(3,)
format=2013-10-23 11:22:39,609 - django.db.backends - DEBUG - (0.000) SELECT (1) AS "a" FROM "versions_image" WHERE "versions_image"."id" = 3  LIMIT 1; args=(3,)
format=2013-10-23 11:22:39,613 - django.db.backends - DEBUG - (0.000) UPDATE "versions_image" SET "version_id" = 1, "image_text" = Zing, "status" = 1, "order" = 0 WHERE "versions_image"."id" = 3 ; args=(1, u'Zing', 1, 0, 3)
format=2013-10-23 11:22:39,621 - django.db.backends - DEBUG - (0.000) SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE ("django_session"."session_key" = kuh0mwboss6q7vmov6ydzs0o1gccsspi  AND "django_session"."expire_date" > 2013-10-23 09:22:39.619910 ); args=('kuh0mwboss6q7vmov6ydzs0o1gccsspi', u'2013-10-23 09:22:39.619910')

为什么图像顺序值没有被保存?

models.py

from django.db import models

class Version(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __unicode__(self):  # Python 3: def __str__(self):
        return self.title

class Image(models.Model):
    version = models.ForeignKey(Version)
    image_text = models.CharField(max_length=200)
    order = models.IntegerField(default=0)

    class Meta:
        ordering = ['order']

    def __unicode__(self):  # Python 3: def __str__(self):
        return self.image_text

urls.py

from django.conf.urls import patterns, url

from versions import views

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<version_id>\d+)/sort/$', views.sort, name='sort'),
)

views.py

from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from versions.models import Image, Version
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def sort(request, version_id):
    for index, image_pk in enumerate(request.POST.getlist('image[]')):
        image = get_object_or_404(Image, pk=int(str(image_pk)))
        image.order = index
        image.save()
        return HttpResponse('')

detail.html

{% extends "base.html" %}

{% block extra_head %}
<script type="text/javascript" charset="utf-8">
  // Sortable photos
  // jQuery and jQuery-UI are in base.html
  $(document).ready(function() {
    $("#sortable").sortable({
      update: function(event, ui) {
        var serial = $('#sortable').sortable('serialize');
    $.ajax({
      url: "{% url 'versions:sort' version.id %}",
      type: "post",
      data: serial
    });
      },
    }).disableSelection();
  });
</script>
{% endblock extra_head %}

{% block content %}
  <h1>{{ version.title }}</h1>
    <ul id="sortable">
    {% for image in version.image_set.all %}
      <li id="image_{{ image.pk }}" class="ui-state-default">
        {{ image.image_text }}
        <span class="move">&#x1F503;</span>
      </li>
    {% endfor %}
    </ul>
{% endblock content %}

1
request.POST.getlist('image[]') 是什么样子?我认为应该是 image 而不是 image[] - Rob L
我已更新问题,并记录了调试信息。由于某种原因,UPDATE 中的顺序始终为0。我尝试过使用 image 而不是 image[],但仍然没有成功。 - sgriffee
好的。只有一张图片,所以它是第一张。因此,它的顺序是“0”。 - Rob L
在我的测试数据中有五张图片。我认为问题是其他方面的原因。感谢您的帮助。 - sgriffee
1
只是想感谢您提供了一个很好的例子,展示如何在Django中使用jQuery Sortable。其他所有的谷歌搜索结果都是关于在Django管理界面中使用它,而这并不是我需要使用它的方式。您的代码,在进行一些调整以适应我的系统后,完美地运行了! - coredumperror
非常感谢您的好意,谢谢。我确定我在其他地方找到了这个信息,但现在不记得了(可能是在原始问题中现在已经失效的链接中)。 - sgriffee
1个回答

3
只需将您的排序视图中的行“return HttpResponse('')”移出循环即可。 感谢实现示例。

非常感谢您——我完全忽略了这一点!我会在我的代码中尝试这个解决方案,并在确认它有效后立即接受它。 - sgriffee
为了使其正常工作,我还需要:1)在views.py中添加from django.views.decorators.csrf import csrf_exempt并使用@csrf_exempt装饰sort视图(以避免405不允许错误)。2)将detail.html中的.ajax url更改为url: "{% url 'detail' version.id %}sort/"。现在它正在工作,再次感谢 - 已接受答案。 - sgriffee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接