Django 5: Within the form, filter data with another field of the same form

Hi everyone, I have a question that I can’t solve.

Form:

  1. I choose country
  2. I choose region 1
  3. I choose region 2

Based on the country I chose, how can I filter the data for region 1?

Code

fk_country = forms.ModelChoiceField(
        label="Pais",
        queryset= PteCountry.objects.all(),
        required=True,
        error_messages={"required": "Introduzca Pais"},
    )
    
    fk_region_1 = forms.ModelChoiceField(
        label="Region 1",
        queryset= PteRegion1.objects.filter(fk_country_id__in=PteCountry.objects.filter(id=**?????**).values_list('id')),
        required=True,
        error_messages={"required": "Introduzca Region 1"},
    )

Are you talking about in the form on the web page? You want this to be updated on the page when a Country is selected?

Correct, the website fills out the form data, when you arrive at the country you choose one, and in “region 1”, the list should only show you the regions of the country.

This technique or method is typically referred to as “chained”, “cascade”, or “dependent” selects. (Those are the typical search terms you’d want to use when searching for this.)

Briefly, doing this involves some JavaScript on the page to catch the change event on the widget. That JavaScript then needs to call a view to get the updated list and update the second selection widget.

There are a couple of packages available to do this sort of thing, but I’m not sure how up-to-date or reliable they are. See GitHub - jazzband/django-smart-selects: chained and grouped selects for django forms as one such example.
Even if you don’t find this specific package to work with what you’re trying to do, the source code would give you some ideas on how to do this.

Also, I believe the Django-Select2 package can do this as well. (See Extra — Django-Select2 8.1.3.dev29+g7333018 documentation)

Thanks for the guide, I started using Django in January 2024, and I’m still researching how to use it correctly.

Thanks Luis

Hi,

I am going to share how I solved the problem.

  1. Django-smart-selects, was the first option but I couldn’t run the demo. Since I am using django 5, according to comments I saw, I should use django 4.x, so ruled out.

  2. Then implement Django-Select2, the solution seems interesting to me.
    Code:

    fk_country = forms.ModelChoiceField(
        queryset=PteCountry.objects.all(),
        label="Pais",
        widget=ModelSelect2Widget(
            model=PteCountry,
            search_fields=["name__icontains"],
            attrs={
                "data-minimum-input-length": 0,
                "data-placeholder": "Tome una opción",
                "data-close-on-select": "true",
            }
        ),
    )
    
    fk_region_1 = forms.ModelChoiceField(
        queryset=PteRegion1.objects.all(),
        label="Departamento",
        widget=ModelSelect2Widget(
            model=PteRegion1,
            search_fields=['name__icontains'],
            dependent_fields={'fk_country': 'fk_country'},
            max_results=500,
            attrs={
                "data-minimum-input-length": 0,
                "data-placeholder": "Tome una opción",
                "data-close-on-select": "true",
            }
        )
    )
   

    #dependent_fields={'fk_country': 'fk_country','fk_region_1': 'fk_region_1'},
    fk_region_2 = forms.ModelChoiceField(
        queryset=PteRegion2.objects.all(),
        label="Municipio",
        widget=ModelSelect2Widget(
            model=PteRegion2,
            search_fields=['name__icontains'],
            dependent_fields={'fk_region_1': 'fk_id_region_1'},
            max_results=500,
            attrs={
                "data-minimum-input-length": 0,
                "data-placeholder": "Tome una opción",
                "data-close-on-select": "true",
            }
        )
    )

It is important to follow the entire guide
https://django-select2.readthedocs.io/en/latest/django_select2.html#module-django_select2.conf

thanks for the help @KenWhitesell