Django管理员内联中的“国家/州/城市”下拉菜单

我有一个按BusinessBranch模型输入的城市外键。我的城市模型还具有州和县模型的州和国家外键。我很难在BusinessBranchInline中显示州和国家/地区下拉菜单。实现这一目标的最佳方法是什么?如果下拉列表根据其父项的值过滤项目,那就太好了。

回答:

有了一点黑客,这是相当可行的。

在以下示例中,使用County代替State和Municipality代替City。因此,模型如下:

class County(models.Model):

name = models.CharField(_('Name'), max_length=100, unique=True)

class Municipality(models.Model):

county = models.ForeignKey(County, verbose_name=_('County'))

name = models.CharField(_('Name'), max_length=100)

class Location(models.Model):

name = models.CharField(max_length=100)

county = models.ForeignKey(County, verbose_name=_('County'))

municipality = models.ForeignKey(Municipality,

verbose_name=_("Municipality"))

问题有两个方面:客户端JavaScript和服务器端字段呈现。

客户端JavaScript(使用JQuery,假定从/site_media/js/municipality.js提供)如下:

var response_cache = {};

function fill_municipalities(county_id) {

if (response_cache[county_id]) {

$("#id_municipality").html(response_cache[county_id]);

} else {

$.getJSON("/municipalities_for_county/", {county_id: county_id},

function(ret, textStatus) {

var options = '<option value="" selected="selected">---------</option>';

for (var i in ret) {

options += '<option value="' + ret[i].id + '">'

+ ret[i].name + '</option>';

}

response_cache[county_id] = options;

$("#id_municipality").html(options);

});

}

}

$(document).ready(function() {

$("#id_county").change(function() { fill_municipalities($(this).val()); });

});

现在,您需要Ajax视图来服务属于给定县的市政当局(假定从/ municipalities_for_county /服务):

from django.http import JSONResponse

from django.utils.encoding import smart_unicode

from django.utils import simplejson

from myproject.places.models import Municipality

def municipalities_for_county(request):

if request.is_ajax() and request.GET and 'county_id' in request.GET:

objs = Municipality.objects.filter(county=request.GET['county_id'])

return JSONResponse([{'id': o.id, 'name': smart_unicode(o)}

for o in objs])

else:

return JSONResponse({'error': 'Not Ajax or no GET'})

最后,admin.py中用于呈现该字段的服务器端代码如下。一,进口:

from django import forms

from django.forms import widgets

from django.forms.util import flatatt

from django.utils.encoding import smart_unicode

from django.utils.safestring import mark_safe

from django.contrib import admin

from django.utils.translation import ugettext_lazy

from myproject.places.models import Municipality, Location

然后,小部件:

class MunicipalityChoiceWidget(widgets.Select):

def render(self, name, value, attrs=None, choices=()):

self.choices = [(u"", u"---------")]

if value is None:

# if no municipality has been previously selected,

# render either an empty list or, if a county has

# been selected, render its municipalities

value = ''

model_obj = self.form_instance.instance

if model_obj and model_obj.county:

for m in model_obj.county.municipality_set.all():

self.choices.append((m.id, smart_unicode(m)))

else:

# if a municipality X has been selected,

# render only these municipalities, that belong

# to X's county

obj = Municipality.objects.get(id=value)

for m in Municipality.objects.filter(county=obj.county):

self.choices.append((m.id, smart_unicode(m)))

# copy-paste from widgets.Select.render

final_attrs = self.build_attrs(attrs, name=name)

output = [u'<select%s>' % flatatt(final_attrs)]

options = self.render_options(choices, [value])

if options:

output.append(options)

output.append('</select>')

return mark_safe(u'\n'.join(output))

接下来,形式:

class LocationForm(forms.ModelForm):

municipality = forms.ModelChoiceField(Municipality.objects,

widget=MunicipalityChoiceWidget(),

label=ugettext_lazy("Municipality"), required=False)

class Meta:

model = Location

def __init__(self, *args, **kwargs):

"""

We need access to the county field in the municipality widget, so we

have to associate the form instance with the widget.

"""

super(LocationForm, self).__init__(*args, **kwargs)

self.fields['municipality'].widget.form_instance = self

最后是admin类:

class LocationAdmin(admin.ModelAdmin):

form = LocationForm

class Media:

js = ('http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js',

'/site_media/js/municipality.js')

admin.site.register(Location, LocationAdmin)

让我知道是否还有不清楚的地方。

以上是 Django管理员内联中的“国家/州/城市”下拉菜单 的全部内容, 来源链接: utcz.com/qa/418351.html

回到顶部