ИМ
21 декабря 2018 г. 19:44

Подскажите по фильтрации объектов в админ-панели

django

Доброго времени суток. У меня ситуация следующая, имею 3 модели которые принадлежат один ко многим:

class Serial(models.Model):
    class Meta:
        db_table = 'serial'
        verbose_name = 'Сериал'
        verbose_name_plural = 'Сериалы'

    name = models.CharField(verbose_name='Название', max_length=200)
    orig_name = models.CharField(verbose_name='Оригинальное название', max_length=200, blank=True)
    poster = models.ImageField(
        # upload_to=curry(upload_to_media, prefix='posters'),
        upload_to=upload_to_media,
        blank=True,
        verbose_name='Постер'
    )
    category = models.ForeignKey(CategorySerial, on_delete=models.CASCADE, verbose_name='Категория', null=True, blank=True)
    year = models.DateField(verbose_name='Дата выхода', default='2000-01-01')
    country = models.CharField(verbose_name='Страна', max_length=300, default='Неизвестно')
    translate = models.CharField(verbose_name='Перевод', max_length=300, default='Русский')
    create = models.DateTimeField(verbose_name='Дата публикации', default=timezone.now)
    update = models.DateTimeField(verbose_name='Дата обновления', default=timezone.now)
    description = models.TextField(verbose_name='Описание')
    moder = models.BooleanField(verbose_name='Модерация', default=False)
    votes = GenericRelation(LikeDislike, related_query_name='serials')

    def public(self):
        self.date = timezone.now()
        self.save()

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('serial:serial_detail', args=[self.id])

    def get_bookmark_count(self):
        return self.bookmarkserial_set.all().count()


class Playlist(models.Model):
    class Meta:
        db_table = 'playlist'
        verbose_name = 'Плейлист'
        verbose_name_plural = 'Плейлисты'
    name = models.CharField(max_length=250, verbose_name='Имя плейлиста')
    serial = models.ForeignKey(Serial, on_delete=models.CASCADE)

    def __str__(self):
        return self.name



class Seria(models.Model):
    class Meta:
        db_table = 'seria'
        verbose_name = 'Серия'
        verbose_name_plural = 'Серии'

    playlist = models.ForeignKey(Playlist, on_delete=models.CASCADE)
    serial = models.ForeignKey(Serial, on_delete=models.CASCADE)
    video = models.FileField(
        # upload_to=curry(upload_to_media, prefix='movies'),
        upload_to=upload_to_media,
        verbose_name='Видео'
    )

В админ панели ситуация следующая: Создал я плейлист в одной сериале, и добавляя видео в другом сериале у меня плейлисты с предыдущего

Вопрос заключается в следующем: как отображать плейлисты только принадлежащие к определенному сериалу а не весь список плейлистов.

Виртуальный хостинг со скидкой 10 процентов
Виртуальный хостинг со скидкой 10 процентов
EVILEG предлагает надёжный хостинг со скидкой 10% на виртуальный хостинг и 5% на VPS
12

Добрый день.

Это делается через установку кастомной формы для model.Admin

Смысл в том, чтобы в соответствующем поле отфильтровать только те серии, или плейлисты, которые отностятся к данном сериалу

class SeriaAdminForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        try:
            self.fields['playlist'].queryset = self.instance.serial.playlist_set.all()
        except Playlist.DoesNotExist:
            pass


class SeriaAdmin(PostAdmin):
    form = SeriaAdminForm


admin.site.register(Seria, SeriaAdmin)

По идее так должно работать правильно.

ИМ

Так то оно работает, но я использую Inline. В inline не хочет, пишет:

serial.models.Seria.serial.RelatedObjectDoesNotExist: Seria has no serial.

Ну, полагаю, что весь прикол в том, что здесь просто не обработано это исключение. Поскольку при создании нового объекта там никакой объект не создан.

А если так? Нужно тогда обработать это исключение и всё

class SeriaAdminForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        try:
            self.fields['playlist'].queryset = self.instance.serial.playlist_set.all()
        except Playlist.DoesNotExist:
            pass
        except Seria.serial.RelatedObjectDoesNotExist:
            pass

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

Дальше я бы покопал в сторону обновления queryset плейлистов в случае изменения внешнего ключа на сериал.

ИМ

Я ошибся. Вышеуказанные формы не работают. А с добавлением except Seria.serial.RelatedObjectDoesNotExist: пропускает ошибку, и в выпадающем списке все плейлисты.

Возможно, тогда стоит установить пустой queryset в том случае если нет внешнего ключа на сериал.

class SeriaAdminForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        try:
            self.fields['playlist'].queryset = self.instance.serial.playlist_set.all()
        except Playlist.DoesNotExist:
            pass
        except Seria.serial.RelatedObjectDoesNotExist:
            self.fields['playlist'].queryset = Playlist.objects.none()

В любом случае, пока не установлен ключ на сериал, то по логике вы не можете установить какой-либо плейлист туда

ИМ

А так в выпадающем списке ничего нет(

Нужно тогда усложнять код, поскольку серия ещё не создана, то нужно сначала получить внешний ключ на парента

class MyFormSet(BaseInlineFormSet):
    def get_form_kwargs(self, index):
        kwargs = super().get_form_kwargs(index)
        kwargs['parent_object'] = self.instance
        return kwargs


class MyForm(forms.ModelForm):
    def __init__(self, *args, parent_object, **kwargs):
        self.parent_object = parent_object
        super(MyForm, self).__init__(*args, **kwargs)

       try:
            self.fields['playlist'].queryset = parent_object.playlist_set.all()
        except Playlist.DoesNotExist:
            pass


class MyChildInline(admin.TabularInline):
    formset = MyFormSet
    form = MyForm

что-то вроде такого должно получиться.

ИМ

Вместо parent_object подставлять serial?

UPD: У меня отступы сдвинулись.

ИМ

Так все работает. Спасибо вам огромное. Учусь с вами потихоньку.

Отступы? какие отступы? в админке? это уже детали, которые просто нужно будет дооправить в дальнейшем.

ИМ

У меня try сьехал влево, сначала не за метил и получал ошибки. Почудилось мне что нужно свои переменные подставлять))

А копировали просто с моего комментария. Там действительно съехал на один пробел. Ну я редактировал сразу в форме комментария текст.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Ищу работу?
14,000.00 руб. - 40,000.00 руб.
Разработчик Qt
Annino, Moscow Oblast, Russia
5,000.00 руб. - 15,000.00 руб.
Дизайнер
Moskovskiy, Moscow, Russia
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы

А
22 августа 2019 г. 23:24
Александр73

Qt - Тест 001. Сигналы и слоты

  • Результат:47баллов,
  • Очки рейтинга-6
21 августа 2019 г. 10:23
Андрей Ермошин

C++ - Тест 002. Константы

  • Результат:58баллов,
  • Очки рейтинга-2
21 августа 2019 г. 10:15
Андрей Ермошин

C++ - Тест 001. Первая программа и типы данных

  • Результат:86баллов,
  • Очки рейтинга6
Последние комментарии
19 августа 2019 г. 7:41
Андрей Янкович

это проблема дистрибутива, попробуйте установить через пакетный менеджер snap Суть проблемы: libQt5Core которая лежит в дистрибутиве требует версию glibc >= 2.25 у вас видимо …
b
18 августа 2019 г. 6:09
bbb116

cqtdeployer /home/aleks/CQtDeployer/bin/cqtdeployer: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /home/aleks/CQtDeployer/lib/libQt5Core.so.5) linux mint …
D
17 августа 2019 г. 9:04
Damir

github ChekableTView Правой групповая смена значения при перетаскивании левой как обычно.
Сейчас обсуждают на форуме
24 августа 2019 г. 7:21
Евгений Легоцкой

Не помню, давно уже с QML не работал, по-моему, обычно пишет в консоль, что не находит файл. В любом случае какую-то ошибку в консоль выкидывает. Но если честно, если у вас проект будет ак…
БГ
24 августа 2019 г. 4:27
Брюс Глифф

Спасибо, вначале в документации было не понятно что к чему, теперь разобрался
I
21 августа 2019 г. 8:36
Intruder

Александр, мне не нужно перебирать. Вы говорите правильно, сначала я написал избыточный код просто не подумав. Задача такая, мне нужно просто переложить из QMap в атрибуты xml тега все, что там …
21 августа 2019 г. 4:46
IscanderChe

Спасибо! Получилось.
21 августа 2019 г. 3:16
nayk1982

Если Вы разрабатываете какую-то универсальную утилиту, которая вообще не привязана к логике, тогда как вариант: 1. Получить список таблиц через QSqlDatabase::tables 2. Для каждой табли…
EVILEG
О нас
Услуги
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB