Фильтр ManyToMany box в Django Admin

У меня есть объект с отношением "многие ко многим" с другим объектом.
В Администраторе Django это приводит к очень длинному списку в поле множественного выбора.

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

это возможно? Должен ли я Создать виджет для него? И если да - как мне скопировать поведение из стандартного поля ManyToMany в него, так как я хотел бы функция filter_horizontal также.

Это мои упрощенные модели:

class City(models.Model):
    name = models.CharField(max_length=200)


class Category(models.Model):
    name = models.CharField(max_length=200)
    available_in = models.ManyToManyField(City)


class Customer(models.Model):
    name = models.CharField(max_length=200)
    city = models.ForeignKey(City)
    categories = models.ManyToManyField(Category)

7 ответов


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

это именно то, что я искал, и я нашел свое решение здесь:http://www.slideshare.net/lincolnloop/customizing-the-django-admin#stats-bottom (слайд 50)

добавьте в мой admin.py:

class CustomerForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs):
        super(CustomerForm, self).__init__(*args, **kwargs)
        wtf = Category.objects.filter(pk=self.instance.cat_id);
        w = self.fields['categories'].widget
        choices = []
        for choice in wtf:
            choices.append((choice.id, choice.name))
        w.choices = choices


class CustomerAdmin(admin.ModelAdmin):
    list_per_page = 100
    ordering = ['submit_date',] # didnt have this one in the example, sorry
    search_fields = ['name', 'city',]
    filter_horizontal = ('categories',)
    form = CustomerForm

это фильтрует список "категории" без удаления каких-либо функций! (ie: я все еще могу иметь мой любимый filter_horizontal:))

ModelForms очень мощный, я немного удивлен, что он не охвачен больше в документации/книге.


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

вы можете сделать именно это с помощью


другой способ-с formfield_for_manytomany в админке Django.

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "cars":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

учитывая, что" автомобили " - это поле ManyToMany.

Регистрация этой ссылке для получения дополнительной информации.


Я думаю, что это то, что вы ищете:

http://blog.philippmetzler.com/?p=52

мы используем django-smart-selects:

http://github.com/digi604/django-smart-selects

Филипп


поскольку вы выбираете город и категории клиента в той же форме, вам понадобится javascript, чтобы динамически сокращать селектор категорий только до категорий, доступных в выбранном городе.


Как говорит Райан, должен быть некоторый javascript для динамического изменения параметров на основе того, что выбирает пользователь. Опубликованное решение работает, если город сохранен, а форма администратора перезагружена, когда фильтр работает, но подумайте о ситуации, когда пользователь хочет отредактировать объект, а затем изменяет выпадающий город, но параметры в категории не будут обновляться.


Category.objects.filter(available_in=cityobject)

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