Filter city field (for each province) based on selected province field in django admin panel
class Province(models.Model):
name = models.CharField( max_length=70, unique=True, null=True, blank=True,)
def __str__(self):
return self.name
class City(models.Model):
province = models.ForeignKey("election.Province", on_delete=models.CASCADE)
name = models.CharField(max_length=70, unique=True, null=True, blank=True,)
class Election(models.Model):
province = models.ForeignKey("election.Province", on_delete=models.SET_NULL, null=True, blank=True,)
city = models.ForeignKey("election.City", on_delete=models.SET_NULL, null=True, blank=True,)
I have this models.
in admin panel, when selecting a province I want to just see the cites that belonging to that province.
I`m begginer ;)
Dynamically, without extra JS workload*, you can't :/
However if Election model is already saved and province on it set, you can limit queryset for cities with:
class ElectionAdmin(...):
[...]
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "city":
election_id = request.resolver_match.kwargs.get("object_id")
election = Election.objects.filter(id=election_id).first()
if election and election.province:
kwargs["queryset"] = City.objects.filter(province=election.province)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
--
* JS algorithm would look something like:
- add event listener (on 'input') to Province input
- query CityAdmin (look into
ModelAdmin.search_fieldsprop) for cities with queried province set - update City input (select options in this case)
You might also take a closer look at ModelAdmin.autocomplete_fields
An idea could be to work with django-smart-selects [readthedocs.io]. You install this by following the installation section of the documentation [readthedocs.io], and redefine the city field as:
from smart_selects.db_fields import ChainedForeignKey
class Election(models.Model):
province = models.ForeignKey(
'election.Province', on_delete=models.SET_NULL, null=True, blank=True
)
city = ChainedForeignKey(
'election.City',
on_delete=models.SET_NULL,
null=True,
blank=True,
chained_field='province',
chained_model_field='province',
show_all=False,
auto_choose=True,
sort=True,
)
This will make AJAX requests to dynamically filter the items based on the other field(s).