Использование трясогузки "ChoiceBlock" с динамическим выбором c вместо жестко закодированного списка - PullRequest
1 голос
/ 01 апреля 2020

У нас есть настройка с моделью блога, которая имеет множество связей для BlogPageCategory, и у нас есть блок потока «последние публикации в блоге», который позволяет вам указать, показывать ли карты для X последних сообщений в блоге или X последних сообщений в блоге от конкретная c категория.

Таким образом, мы начали со следующего кода:

from wagtail.core import blocks


class RecentBlogEntries(blocks.StructBlock):
    title = blocks.CharBlock(
        required=True,
    )

    category_filter = blocks.ChoiceBlock(
        label='Filter by Category',
        required=False,
        choices=[
            ('all', 'All'),
            ('First Category', 'First Category'),
            ('...',. '...'),
        ],
    )

    ...

Но жесткое кодирование категорий довольно глупо, и мы можем выбрать их из того, что есть в списке прямо сейчас, на основе данных CMS для BlogPageCategory "будет гораздо удобнее. Однако следующий код (разумеется) превращается в столь же жестко запрограммированную миграцию:

from wagtail.core import blocks
from ... import BlogPageCategory


class RecentBlogEntries(blocks.StructBlock):
    title = blocks.CharBlock(
        required=True,
    )

    choices = [ (cat.name, cat.name) for cat in BlogPageCategory.objects.all()]
    choices.sort()
    choices.insert(0, ('all', 'All'))

    category_filter = blocks.ChoiceBlock(
        label='Filter by Category',
        required=False,
        choices=choices,
    )

    ...

Можно ли сделать это значение динамическим c вместо списка, который фиксирован makemigrations?

1 Ответ

3 голосов
/ 01 апреля 2020

ChoiceBlock принимает вызываемую функцию в качестве аргумента choices:

def get_categories():
    return [(cat.name, cat.name) for cat in BlogPageCategory.objects.all()]


class RecentBlogEntries(blocks.StructBlock):
    title = blocks.CharBlock(
        required=True,
    )

    category_filter = blocks.ChoiceBlock(
        label='Filter by Category',
        required=False,
        choices=get_categories,
    )

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

...