Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Фильтрация элементов поля по общему полю в django admin

#python #django #django_admin #django_filter


изучаю django, и застрял на вопросе как сделать фильтрацию. 

Простая фильтрация с использованием filter_horizontal = ('field name') к сожалению
мне не подходит, т.к он фильтрует по имени элемента а не по общему полю( 
Нужна примерна такая реализация как это делается list_filter = ['field name'], но
т.к мое поле указывает инлайново(скрин 1), list_filter соответственно не работает.

Пример такой, у меня есть 4 элементов.


name = Белый , material = Дуб
name = Красный, material = Дуб
name = пурпурный, material = Метал
name = глянцевый, material = Метал


И мне при заполнение в Админки товара надо выдать не общим списком manyToManyField(на
скрине есть это поле) и фильтром filter_horizontal, который будет фильтровать по name,
а нужен фильтр который бы фильтровал по полю material, то есть по общему значению(скрин
2, как это реализуется стандартным list_filter. Реально ли такое реализовать? может
есть какой виджет? Пытался копать в сторону get_ordering, но не понимаю как в него
каждый раз передавать material. 





Модели models.py

#модель для вывода inlines у товара
class ImgPropertyMaterialProduct(models.Model):
   product = models.ForeignKey(Product)
   material = models.ForeignKey(MaterialPropery)
   colors = models.ManyToManyField(ImgPropertyMaterial, blank=True, verbose_name='Цвета')

#модель для заполнения property
class ImgPropertyMaterial(models.Model):
    position = models.CharField(max_length=5, verbose_name='Позиция для сортировки')
    material = models.ForeignKey(MaterialPropery)
    type = models.CharField(max_length=40, default='color', db_index=True,
                            choices=(('color', 'Цвет'), ('texture', 'Текстура')))
    value = models.CharField(max_length=40, unique=True, verbose_name='Значение')
    photo = models.ImageField(upload_to=PhotoPath('color_propery/photo'), null=True,
verbose_name='Фото')

    class Meta:
        verbose_name = 'Свойство: Изображение материала'
        verbose_name_plural = 'Свойство: Изображение материалов'

    def __str__(self):
        return self.value


И обычный горизонтальный фильтр в админки

class RowInlineTwo(admin.StackedInline):
    model = ImgPropertyMaterialProduct
    filter_horizontal = ('colors',)

    


Ответы

Ответ 1



У вас очень сумбурный текст вопроса. Я так и не смог понять, что же вам всё таки нужно - list_filter или filter_horizontal. Если первое, то всё просто: list_filter = ['colors__material'] А если надо ограничить элементы доступные в filter_horizontal, то чуточку сложнее: class ProductAdmin(admin.ModelAdmin): filter_horizontal = ['colors'] def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name == 'colors': obj_id = request.resolver_match.kwargs['object_id'] obj = self.get_object(request, obj_id) kwargs['queryset'] = ImgPropertyMaterial.objects.filter(material=obj.material) return super().formfield_for_manytomany(db_field, request, **kwargs)

Комментариев нет:

Отправить комментарий