Search code examples
djangoadmindropdown

Django dropdown dependency on admin


i am only using the admin-interface of django , and i have a problem that , when someone select for exemple " country " i want to show on the second select the "city's " of that country.I have already done , my json file on my view and i want to get my json file and show it in javascript, and i dont know how to do it.

MY APLICATION:

myproject/
     |-- myproject
     |-- daa/
         |-- avarias/
            |-- models.py
     |-- mapeamento/
          |-- models.py
          |-- views.py
     |-- static/
          |-- daa/
            |-- avarias/
              |-- admin/
                |-- js/
                  |-- example.js     
     |-- templates/
          |-- admin/
              |-- daa/
                  |-- change_form.html

MY URLS

urlpatterns = [
    path('', admin.site.urls, name ='home'),
    path('rua/list/', get_ruas, name='get_ruas'),

]

MY MODELS:

#Mapeamento Model

  class Freguesia(models.Model):
    id = models.IntegerField("Freguesia ID", primary_key=True)
    nome = models.CharField("Freguesia",max_length=200)

    def __str__(self):

        return  self.nome

  class Rua(models.Model):
    id = models.IntegerField("Rua id", primary_key=True)
    freguesia = models.ForeignKey(Freguesia, on_delete=models.CASCADE)
    nome = models.CharField("Rua",max_length=200)

    def __str__(self):

        return  self.nome
#daa/avarias Model
    from mapeamento.models import freguesia
    from mapeamento.models import rua

class Avaria(models.Model):
    freguesia = models.ForeignKey(Freguesia, on_delete=models.CASCADE,verbose_name="Freguesia")
    rua = models.ForeignKey(Rua, on_delete=models.CASCADE,verbose_name="Rua")

    def __str__(self,):

        return str(self.id)

MY MAPEAMENTO.VIEW

import json

from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from .models import Freguesia, Rua

def get_ruas(request): 
    freguesia_id = request.GET.get('freguesia_id')
    freguesia = get_object_or_404(Freguesia, pk=freguesia_id)
    res = Rua.objects.filter(freguesia=freguesia).order_by('nome').values('id', 'nome')
    result = {
        'ruas': list(Rua.objects.filter(freguesia=freguesia).order_by('nome').values('id', 'nome'))
    }
    return HttpResponse(json.dumps(result), content_type="application/json")

MY CHANGE_FORM.HTML

   {% extends "admin/change_form.html" %} 

   {% block extrahead %}
   {{ block.super }} 
    <script 
    # DO SOMETHING
   </script>
   {% endblock %}

So right now i dont know what to do , when i go to my browser and put rua/list/?freguesia_id=10001 it is working , but now i want to show that values on my select.


Solution

  • You can try using django autocomplete light. Here are the docs.

    This will give you the functionality to display options in the child filter based on the selection in parent filter with the help of its forward paramater.

    Create a form class with city and country fields and then forward the field to city filter as:

    class YourFormClass(forms.ModelForm):
        country = forms.ModelChoiceField(queryset=Country.objects.all(), 
                                     widget=autocomplete.ModelSelect2(url='your_country_auto_url'),
                                     )
        city = forms.ModelChoiceField(queryset=City.objects.all(),
                                        widget=autocomplete.ModelSelect2(url='your_city_auto_url',
                                                                         forward=['country']))
    
        class Meta:
            model = YourModel
            fields = '__all__'
    

    Department View:

    class YourViewAutocomplete(autocomplete.Select2QuerySetView):
        def get_queryset(self):
            if not self.request.user.is_authenticated():
                return City.objects.none()
    
            qs = City.objects.all()
    
            country = self.forwarded.get('country', None)
    
            if country:
                qs = qs.filter(country=country)
    
            if self.q:
                qs = qs.filter(name__istartswith=self.q)
            return qs
    

    This will forward the selected country id and it can then be used in the autocomplete view to filter the city queryset. Please refer to the documentation to create autocomplete views to be used for the fields in the form.

    Hope it helps.