Джанго админ.Отображение иерархического выпадающего фильтра - PullRequest
3 голосов
/ 07 февраля 2011

У меня есть следующая модель:

from django.db import models

class State(models.Model):
    name = models.CharField(max_length=30)
    abbreviation = models.CharField(max_length=2)

    def numberOfCities(self):
        return self.city_set.count()

    def __unicode__(self):
        return u"{0} - {1}".format(self.abbreviation, self.name)

class City(models.Model):
    name = models.CharField(max_length=40)
    state = models.ForeignKey(State)

    class Meta:
        verbose_name_plural = 'Cities'

    def __unicode__(self):
        return self.name

class Company(models.Model):
    name = models.CharField(max_length=60)
    description = models.CharField(max_length=1000)
    city = models.ForeignKey(City)

    class Meta:
        verbose_name_plural = 'Companies'

    def __unicode__(self):
        return self.name;

Как видите, каждая компания связана с городом, и, как и следовало ожидать, администратор Django генерирует форму создания компании, содержащую раскрывающийся список городов.Но чтобы улучшить взаимодействие с пользователем, я бы хотел, чтобы пользователь сначала выбирал штат, а затем в раскрывающемся списке городов были бы города из этого штата.Есть ли стандартный способ сделать это?

Ответы [ 2 ]

1 голос
/ 07 февраля 2011

Вам нужно создать собственный виджет, чтобы выбрать модель города (то есть ваша модель должна быть FK в город, а не в штат), этот виджет содержит два поля выбора, первое из которых содержит состояния, а второе загружается на выбор штата (вам нужно подключить представление, чтобы вернуть города на основе идентификатора штата, чтобы заполнить ваш выбор города).

Вы должны установить свои виджеты Внутренний класс Media указывает на конкретный файл .js, объединяющий оба Select.

В спецификации ModelAdmin установите виджет вашего поля на пользовательский виджет, который вы только что создали, и его медиа будет автоматически добавлен в шаблон change_form.

Убедитесь, что ваш файл .js ищет ваш обычный объект JQuery и возвращается к django.JQuery, так что вы можете использовать этот же виджет в админке и во всем вашем сайте.

(function($) {
// Note that this function works only for one widget per page
$('#state').change(function(){
    $('#city').load('/cities_by_state/', {id: this.value}); // the endpoint returns HTML
});
})(JQuery||django.JQuery);

Я сделал нечто похожее в приложении, которое я использую локально для своих проектов (с переменной глубиной до трех уровней), и полученное решение оказалось немного сложным, так как оно должно было поддерживать несколько виджетов на страницу, динамические виджеты (для встроенных ), шаблоны тегов для отображения виджета в различных формах и т. д.

1 голос
/ 07 февраля 2011

Согнуть админа нелегко, но это просто еще одно приложение django, хотя и очень сложное.Я обычно делаю что-то вроде этого:

  1. Создайте пользовательский шаблон администратора для рассматриваемой модели (переопределите change_form.html).
  2. Создайте URL-адрес ajaxкоторый возвращает виджет City, отфильтрованный по идентификатору состояния.
  3. Используйте что-то вроде jQuery для замены виджета City при изменении состояния.

Администратор Django Javascript уже использует библиотеку jQuery.Чтобы избежать конфликта с пользовательскими скриптами, jQuery в Django имеет пространство имен django.jQuery.Так что вам не нужно включать вторую копию, вы можете использовать объект django.jQuery в списке изменений и добавлять / редактировать представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...