如何使用 Modelform 和 jquery 在 django 中获取相互依赖的下拉菜单?
Posted
技术标签:
【中文标题】如何使用 Modelform 和 jquery 在 django 中获取相互依赖的下拉菜单?【英文标题】:How to get Interdependent dropdowns in django using Modelform and jquery? 【发布时间】:2012-12-16 18:23:01 【问题描述】:我是 django 和 jquery 的新手。我正在开发一个基于 django 的应用程序,其中一个表单中有 3 个下拉菜单。 1.校园 2.学校 3. 中心
层次结构是校园有学校,学校有中心。我想链接这些下拉菜单。
例如,我有 3 个校区,例如 Campus1、Campus2、Campus3。如果我选择 Campus1,我应该只选择 Campus1 中的学校并继续此操作,如果我选择 School1,那么我需要能够选择 School1 的中心,并且所有其他选项都应该被隐藏。
我在网上搜索并尝试过这个http://blog.devinterface.com/2011/02/how-to-implement-two-dropdowns-dependent-on-each-other-using-django-and-jquery/ 但这似乎对我不起作用。 我也检查了这个http://www.javascriptkit.com/script/script2/triplecombo.shtml 但由于我使用 ModelForm 创建表单,这不符合我的需求。
请指导我这样做。
谢谢
【问题讨论】:
【参考方案1】:您可能需要使用以下技术:
自定义 Django 表单字段(在模型表单内) ajax(获取记录) simplejson(向ajax发送json响应) jquery(更新客户端的组合框)让我们看一个例子(没有真正测试过,只是我的想法):
模型.py
from django.db import models
class Campus(models.Model):
name = models.CharField(max_length=100, choices=choices.CAMPUSES)
def __unicode__(self):
return u'%s' % self.name
class School(models.Model):
name = models.CharField(max_length=100)
campus = models.ForeignKey(Campus)
def __unicode__(self):
return u'%s' % self.name
class Centre(models.Model):
name = models.CharField(max_length=100)
school = models.ForeignKey(School)
def __unicode__(self):
return u'%s' % self.name
Forms.py
import models
from django import forms
class CenterForm(forms.ModelForm):
campus = forms.ModelChoiceField(queryset=models.Campus.objects.all())
school = forms.ModelChoiceField(queryset=models.School.objects.none()) # Need to populate this using jquery
centre = forms.ModelChoiceField(queryset=models.Centre.objects.none()) # Need to populate this using jquery
class Meta:
model = models.Center
fields = ('campus', 'school', 'centre')
现在,在您的视图中编写一个方法,该方法返回一个 json 对象,用于校园下的学校和学校下的中心:
Views.py
import models
import simplejson
from django.http import HttpResponse
def get_schools(request, campus_id):
campus = models.Campus.objects.get(pk=campus_id)
schools = models.School.objects.filter(campus=campus)
school_dict =
for school in schools:
school_dict[school.id] = school.name
return HttpResponse(simplejson.dumps(school_dict), mimetype="application/json")
def get_centres(request, school_id):
school = models.School.objects.get(pk=school_id)
centres = models.Centre.objects.filter(school=school)
centre_dict =
for centre in centres:
centre_dict[centre.id] = centre.name
return HttpResponse(simplejson.dumps(centre_dict), mimetype="application/json")
现在编写一个 ajax/jquery 方法来获取数据并填充 HTML 中的 select
元素。
AJAX/jQuery
$(document).ready(function()
$('select[name=campus]').change(function()
campus_id = $(this).val();
request_url = '/get_schools/' + campus_id + '/';
$.ajax(
url: request_url,
success: function(data)
$.each(data, function(index, text)
$('select[name=school]').append(
$('<option></option>').val(index).html(text)
);
);
);
return false;
)
);
【讨论】:
在任何地方都使用 ModelChoiceField 会使 ModelForm 的用途无效。Select
也是默认小部件,您无需声明它。显然,根据 OP 的描述,学校与具有外键的 Campuses 相关。
我同意如果实际代码仅限于上述示例,它可能会使 ModelForm 的目的无效。请注意模型和表单的实际代码可能会有所不同,以上仅为示例。
当然在表格和模型没有直接对应关系的情况下可能会有所不同。由于 OP 没有明确描述他的模型,我只是同意你只是一个例子。我只是想说明一些对于 django 新手来说可能不会立即显而易见的事情。
无论哪种方式,您都应该为您的完整解决方案获得 +1。
非常感谢您的回复。我会试试这个然后回来。【参考方案2】:
我不会重新发明***,而是使用Django Smart Selects 或Django Autocomplete Light
我还没有尝试过,但我将在即将进行的项目中使用其中一个或两个。
【讨论】:
以上是关于如何使用 Modelform 和 jquery 在 django 中获取相互依赖的下拉菜单?的主要内容,如果未能解决你的问题,请参考以下文章
Django Ajax ModelForm 向 request.POST 提交一个空表单
使用 FormView 和 ModelForm 时如何在模板上获取 non_field_errors
如何在 ModelForm 中使用 forms.ChoiceField()?