问题 如何根据django admin中的另一个选项字段限制选择字段选项


我有以下型号:

class Category(models.Model):
    name = models.CharField(max_length=40)

class Item(models.Model):
    name = models.CharField(max_length=40)
    category = models.ForeignKey(Category)

class Demo(models.Model):
    name = models.CharField(max_length=40)
    category = models.ForeignKey(Category)
    item = models.ForeignKey(Item)

在管理界面中创建新演示时,在用户从下拉列表中选择类别后,我想限制“项目”下拉列表中的选项数量。如果用户选择另一个类别,则项目选项应相应更新。我想在客户端上限制项目选择,甚至在服务器上进行表单验证之前。这是为了可用性,因为项目列表可以是1000+,能够按类别缩小它将有助于使其更易于管理。

是否有“django-way”这样做或自定义JavaScript是唯一的选择?


6754
2018-04-28 06:28


起源

在Django模型中真的没有办法设置它吗? - Instance Hunter
是的,有。使用第三方应用程序。看到我的回答。 - dan-klasson


答案:


以下是一些javascript(基于JQuery)在类别更改时更改项目选项值:

<script charset="utf-8" type="text/javascript">
  $(function(){
    $("select#id_category").change(function(){
      $.getJSON("/items/",{id: $(this).val(), view: 'json'}, function(j) {
        var options = '<option value="">--------&nbsp;</option>';
        for (var i = 0; i < j.length; i++) {
          options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
        }
        $("#id_item").html(options);
        $("#id_item option:first").attr('selected', 'selected');
      })
      $("#id_category").attr('selected', 'selected');
    })
  })
</script>

您需要在/ items / URL上调用视图,该视图提供有效项的JSON列表。

您可以使用将其挂钩到管理员 模型管理媒体定义


10
2018-04-28 07:07



+1 - >我即将发布非常相似的内容。 OP只需要使用db中的信息填充列表,然后使用您提供的JS切换选项:-) - Jon Cage
...或者如果您不想一次性加载它,您可以使用一些ajax在每次用户更改选项时从服务器请求类别。取决于你是否想在预选时采取预防或延迟它们...... - Jon Cage
谢谢乔恩。如果你愿意,你应该继续发布你的代码,在加载时填充列表而不是像我一样的ajax。那么OP可以选择更合适的。 - Van Gale
如果我有一些可以拿到的话,我会想的...... AJAX是Django的一个方面,我还没有尝试过。很快我确定:-) - Jon Cage


Django的智能选择

如果您有以下型号:

class Location(models.Model)
    continent = models.ForeignKey(Continent)
    country = models.ForeignKey(Country)
    area = models.ForeignKey(Area)
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

如果您选择一个大陆,只有那些位于该大陆的国家/地区可用,并且您可以执行以下操作:

from smart_selects.db_fields import ChainedForeignKey 

class Location(models.Model)
    continent = models.ForeignKey(Continent)
    country = ChainedForeignKey(
        Country, 
        chained_field="continent",
        chained_model_field="continent", 
        show_all=False, 
        auto_choose=True
    )
    area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country")
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

5
2017-08-07 01:06





我认为JavaScript / AJAX将是解决此问题的最佳方法。


0
2018-04-28 06:47



看起来更像是对上面答案的评论而不是它自己的答案。 - boatcoder


您将需要某种基于非服务器的过滤对象的机制。或者,或者您可以在进行选择时重新加载页面(无论如何都可能在JavaScript中完成)。

否则,无法将数据子集从服务器获取到客户端。


0
2018-04-28 09:30