Фильтр поля "город" (для каждой провинции) на основе выбранного поля "провинция" в панели администратора django

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

У меня есть эти модели.

в панели администратора при выборе провинции я хочу видеть только те города, которые относятся к этой провинции.
Я новичок ;)

Динамически, без дополнительной нагрузки на JS*, нельзя :/

Однако если модель выборов уже сохранена и провинция на ней установлена, вы можете ограничить набор запросов для городов с помощью:

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 будет выглядеть примерно так:

  1. добавьте слушателя событий (на 'input') для ввода провинции
  2. запросите CityAdmin (посмотрите в ModelAdmin.search_fields prop) для городов с запрошенным набором провинций
  3. обновление ввода города (в данном случае выбор опций)

Вы также можете присмотреться к 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,
    )

При этом будут выполняться AJAX-запросы для динамической фильтрации элементов на основе другого поля (полей).

Вернуться на верх