代码之家  ›  专栏  ›  技术社区  ›  Fred Larson

具有额外项的窗体集的拖放排序

  •  2
  • Fred Larson  · 技术社区  · 15 年前

    我一直在寻找一种允许用户轻松更改表单集中条目顺序的方法。我发现 a StackOverflow question 解决了这个问题,接受的答案引用了 Django Snippet 它使用jquery工具允许拖放条目。这很漂亮很酷,但我对“额外”条目有问题。如果修改了“额外”条目,然后拖动,则提交时会出错:

    (1048, "Column 'order' cannot be null")

    我相信django将“额外”条目分开,因为它们必须被插入而不是更新。因此,重新排序可能会混淆问题。是否有办法使这项工作,或有其他建议重新排序和/或添加新条目?

    编辑:增加了一些相关的代码摘录。如代码片段所示,我正在管理员中尝试这个方法。不过,我最终还是想把它放到我自己的页面上。

    模型:

    class Section(models.Model):
        section_id = models.AutoField(primary_key=True)
        section_name = models.CharField(max_length=135)
        score_order = models.IntegerField()
        def __unicode__(self):
          return self.section_name
        class Meta:
            db_table = u'section'
            ordering = [u"score_order"]
    
    class Chair(models.Model):
        chair_id = models.AutoField(primary_key=True)
        member = models.ForeignKey(Member, null=True, blank=True,
          limit_choices_to={'current_member': True})
        section = models.ForeignKey(Section)
        description = models.CharField(max_length=135)
        order = models.IntegerField(blank=True, null=True)
        def __unicode__(self):
          return "%s - %s" % (self.description, self.member)
        class Meta:
            db_table = u'chair'
            ordering = (u'section', u'order')
    

    行政管理部门

    class SectionForm(forms.ModelForm):
        model = Section
        class Media:
            js = (
                '/scripts/jquery.js',
                '/scripts/ui.core.js',
                '/scripts/ui.sortable.js',
                '/scripts/section-sort.js',
            )
    
    class ChairInline(admin.StackedInline):
        model = Chair
    
    admin.site.register(Section,
                        inlines = [ChairInline],
                        form = SectionForm,
    )
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Fred Larson    15 年前

    我找到了自己的解决办法。代码段正在为具有非空主键值的每一行设置顺序。但是额外的行有一个空的主键,我相信它们必须保持为空以便Django知道它们将被插入而不是更新。我修改了函数以检查其他字段是否为空(幸运的是,我只有几个字段)以及主键:

    jQuery(function($) {
        $('div.inline-group').sortable({
            items: 'div.inline-related',
            handle: 'h3:first',
            update: function() {
                $(this).find('div.inline-related').each(function(i) {
                    if ($(this).find('input[id$=chair_id]').val() ||
                      $(this).find('select[id$=member]').val() ||
                          $(this).find('select[id$=description]').val()) {
                        $(this).find('input[id$=order]').val(i+1);
                    }
                });
            }
        });
        $('div.inline-related h3').css('cursor', 'move');
        $('div.inline-related').find('input[id$=order]').parent('div').hide();
    });
    

    这对我有好处。我可以通过在表单中添加一个隐藏字段来改进它,每当一行中的任何字段被修改时,这个表单都会被设置。但在这一点上,我仍然是一个jquery n00b,所以这就可以了。如果有人有更好的想法,请随时发表评论或添加其他答案。

        2
  •  1
  •   Harold    15 年前

    我在我的一个应用程序中做可排序的表单集。我使用这个jquery拖放插件:

    http://www.isocra.com/2008/02/table-drag-and-drop-jquery-plugin/

    我将插件的OnDrop事件绑定到一个重置所有“order”字段值的函数。

    此外,我将初始数据传递给表单集,以便在没有可用的javascript的情况下,表单集的额外“order”字段始终具有值-用户将无法重新排序行,但他们可以编辑和发布更改,而不会出现您描述的空错误。