Подтвердить что ты не робот

Фильтр ManyToMany в Django Admin

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

Я хотел бы отфильтровать отношение 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)
4b9b3361

Ответ 1

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

Это именно то, что я искал, и нашел свое решение здесь: 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

Это фильтрует список категорий, не удаляя никаких функций! (то есть: у меня все еще может быть мой любимый filter_horizontal:))

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

Ответ 2

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

Вы можете сделать именно это, используя атрибут limit_choices_to models.ManyToManyField. Поэтому изменение определения модели в качестве...

class Customer(models.Model):
    name = models.CharField(max_length=200)
    city = models.ForeignKey(City)
    categories = models.ManyToManyField(Category, limit_choices_to = {'available_in': cityId})

Это должно работать, поскольку limit_choices_to доступно для этой цели.

Но одно замечание: limit_choices_to не имеет эффекта при использовании на ManyToManyField с пользовательской промежуточной таблицей. Надеюсь, это поможет.

Ответ 3

Другим способом является formfield_for_manytomany в Django Admin.

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.

За дополнительной информацией обращайтесь эту ссылку.

Ответ 5

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

Ответ 6

Category.objects.filter(available_in=cityobject)

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

Ответ 7

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