2009-11-04 9 views
8

के अंदर देश/राज्य/शहर ड्रॉपडाउन मेनू, मेरे पास बिजनेस ब्रंच मॉडल द्वारा एक शहर की विदेशी कुंजी है। मेरे सिटी मॉडल में राज्य और काउंटी मॉडल के लिए एक राज्य और देश की विदेशी कुंजी भी है। मुझे अपने बिजनेस ब्रांचइनलाइन के अंदर राज्य और देश ड्रॉपडाउन मेनू प्रदर्शित करने में कठिनाई हो रही है। इसे हासिल करने का सबसे अच्छा तरीका क्या होगा? यह बहुत अच्छा होगा अगर ड्रॉपडाउन फ़िल्टर आइटम अपने माता-पिता के मूल्य के आधार पर फ़िल्टर करें।Django व्यवस्थापक इनलाइन

django admin screenshot http://i33.tinypic.com/15n69mq.png

उत्तर

23

के लिए dajaxproject की Ajax Form Machine उपयोग कर सकते हैं एक छोटे से hackery के साथ, यह काफी संभव है।

निम्न उदाहरण में, काउंटीराज्य और नगर पालिकाके बजाय शहर के बजाय प्रयोग किया जाता है। तो, मॉडल निम्नानुसार हैं:

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")) 

समस्या के दो पक्ष हैं: क्लाइंट-साइड जावास्क्रिप्ट और सर्वर साइड फ़ील्ड प्रतिपादन।

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()); }); 
}); 

अब आप नगर पालिकाओं कि संबंधित सेवा के लिए अजाक्स देखने की जरूरत है:

क्लाइंट पक्ष जावास्क्रिप्ट इस प्रकार है (JQuery के साथ, /site_media/js/municipality.js से प्रस्तुत किया जाना माना) किसी दिए गए काउंटी के लिए (/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'}) 

और व्यवस्थापक में अंत में सर्वर साइड कोड। क्षेत्र को प्रतिपादित करने के लिए 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 

और अंत में, व्यवस्थापक वर्ग:

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) 

मुझे कुछ बताएं अगर कुछ बात अस्पष्ट बनी हुई है।

+5

+1 इस तरह के एक बहुत ही व्यापक जवाब के लिए +1।मैं कुछ ऐसा करने जा रहा हूं और हालांकि मैं व्यवस्थापक का उपयोग नहीं कर रहा हूं, यह बहुत मददगार होना चाहिए। धन्यवाद! –

+1

धन्यवाद - एक सज्जन और विद्वान। – snakesNbronies

+0

'mimitype' है (django 1.6) बहिष्कृत। मुझे लगता है कि आपको इसे 'content_type' से बदलना होगा। – suhailvs

0

आप एक कस्टम "पता" विजेट है कि तीन ड्रॉपडाउन के साथ व्यापक संभालती बनाने के लिए देखने के लिए चाहते हो सकता है। आप इस पर मार्गदर्शन के लिए डेटटाइम विजेट के स्रोत कोड को देखना चाहेंगे।

इसके अलावा, this one जैसे कस्टम विजेट बनाने पर ट्यूटोरियल देखें।

0

यह बहुत अच्छा होगा अगर ड्रॉपडाउन फ़िल्टर आइटम अपने माता-पिता के मूल्य के आधार पर फ़िल्टर करें।

आप उस भाग

संबंधित मुद्दे