Reputation: 3
I'm new about programming so my code could seems dumb sometimes.
I'm stuck on this problem since 2 days and I looked for on the web but didn't find what I wanted. I saw related questions on stackoverflow but it seems it?s only for forms and I would like to implement that in the Admin interface.
I would like to display choices in a dropdown menu depending on the choices the user make in an other dropdown menu.
Here my model:
class Airport(BaseModel):
airport_code = models.CharField(max_length=50, verbose_name="Airport Code (ICAO)")
airport_name = models.CharField(max_length=50, verbose_name="Airport Name")
country = models.ForeignKey('cities_light.Country', verbose_name='Country')
state = models.ForeignKey('cities_light.Region', verbose_name='Region')
city = models.ForeignKey('cities_light.City', verbose_name='City')
pass
# Afficher dans la partie Admin la valeur au lieu des objets
def __str__(self):
return 'Airport: {}'.format(self.value)
All that, in the Admin :)
Thanks so much !
Upvotes: 0
Views: 3084
Reputation: 603
I suggest to use a different data structure:
{"USA": ["Alabama", "Alaska"], "Canada": ["Ontario", "Quebec"]}
Then in models.py you can load/store the dict in this way:
class Airport(BaseModel):
airport_code = models.CharField(max_length=50, verbose_name="Airport Code (ICAO)")
airport_name = models.CharField(max_length=50, verbose_name="Airport Name")
city = models.CharField(max_length=50, verbose_name="City")
country = models.TextField(blank=True, null=True)
def setlist(self, x):
self.country = json.dumps(x)
@property
def getlist(self):
if self.country:
return json.loads(self.country)
else:
return {}
In view.py:
@login_required
def show_airport(request):
airport = Airport.objects.first()
return render(
request,
'your_template.html',
{'airport': airport}
)
So in template will be easier to iterate over keys and values to generate related menus:
{% for key, value in airport.getlist.items %}
<p>{{key}}: {{value}} </p>
{% endfor %}
Then you can manage user choices client side with javascript with something like:
<form>
<select id="nation">
{% for key, value in airport.getlist.items %}
<option value="{{key}}">{{key}}</option>
{% endfor %}
</select>
<select id="states">
</select>
</form>
<script>
country_list = {{ airport.getlist.items|safe }};
jQuery.each(country_list[$('#nation').val()], function() {
$("#states").append('<option value="' + this + '">' + this + '</option>')
});
$('#nation').on('change', function(event){
$('#states').empty()
jQuery.each(country_list[$('#nation').val()], function() {
$("#states").append('<option value="' + this + '">' + this + '</option>')
});
});
</script>
UPDATE:
Country example using django-autocomplete-light module inside django admin:
pip install django-autocomplete-light
settings.py
INSTALLED_APPS = [
'dal',
'dal_select2',
'django.contrib.admin',
...
urls.py
from django.conf.urls import url
from django.contrib import admin
from countryTest.views import CountryAutocompleteFromList
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test-country/$', CountryAutocompleteFromList.as_view(), name="country-list-autocomplete")
]
views.py
from dal.autocomplete import Select2ListView
class CountryAutocompleteFromList(Select2ListView):
def get_list(self):
continent = self.forwarded.get('continent', None)
qs = {
'Usa': ['California', 'Kansas'],
'Canada': ['Quebec', 'Ontario']}
if continent:
return qs[continent]
admin.py
from countryTest.models import Country
from django.contrib import admin
from countryTest.forms import CountryForm
class CountryAdmin(admin.ModelAdmin):
form = CountryForm
model = Country
admin.site.register(Country, CountryAdmin)
models.py
from django.db import models
class Country(models.Model):
continent = models.CharField(max_length=250, null=True)
state = models.CharField(max_length=250, null=True)
def __unicode__(self):
return " ".join((str(self.continent), str(self.state)))
forms.py
from dal import autocomplete
from django import forms
CONTINENT_CHOICES = (('Usa', 'Usa'), ('Canada', 'Canada'))
def get_choices_list():
return ['Quebec', 'Ontario', 'Kansas', 'California']
class CountryForm(forms.ModelForm):
continent = forms.ChoiceField(choices=CONTINENT_CHOICES)
state = autocomplete.Select2ListChoiceField(
choice_list=get_choices_list,
widget=autocomplete.ListSelect2(url='country-list-autocomplete', forward=['continent'])
)
Upvotes: 1