Заполнение виджета CheckboxSelectMultiple с использованием моей собственной модели в администраторе WagtailPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Заполнение виджета CheckboxSelectMultiple с использованием моей собственной модели в администраторе Wagtail

Сообщение Anonymous »

Контекст
Я создал модель, соответствующую модели поля, и намерен повторно использовать встроенный виджет CheckboxSelectMultiple для использования в администраторе Wagtail< /эм>. Идея заключается в поле разрешения с множественным выбором, которое сохраняется как битовое поле:

Код: Выделить всё

# Model class
class Perm(IntFlag):
Empty  = 0
Read   = 1
Write  = 2
Я использовал документацию по полю модели Django, чтобы создать модель поля, которая может транслировать мой тип Perm в мою базу данных и из нее (сохраняется как целочисленное поле, которое побитово ИЛИ соответствующих битов разрешения). ):

Код: Выделить всё

# Model field class
class PermField(models.Field):
description = "Permission field"
def __init__(self, value=Perm.Empty.value, *args, **kwargs):
self.value = value
kwargs["default"] = Perm.Empty.value
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
args += [self.value]
return name, path, args, kwargs
def db_type(self, connection):
return "bigint" # PostgresSQL
def from_db_value(self, value, expression, connection):
if value is None:
return Perm.Empty
return Perm(value)
def to_python(self, value):
if isinstance(value, Perm):
return value
if isinstance(value, str):
return self.parse(value)
if value is None:
return value
return Perm(value)
def parse(self, value):
v = Perm.Empty
if not isinstance(ast.literal_eval(value), list):
raise ValueError("%s cannot be converted to %s", value, type(Perm))
for n in ast.literal_eval(value):
v = v | Perm(int(n))
return v
Затем я также создал фрагмент Wagtail, чтобы использовать это новое поле и ввести:

Код: Выделить всё

perm_choices = [
(Perm.Read.value, Perm.Read.name),
(Perm.Write.value, Perm.Write.name)
]

@register_snippet
class Permission(models.Model):
name = models.CharField(max_length=32, default="None")
perm = PermField()
panels = [FieldPanel("perm", widget=forms.CheckboxSelectMultiple(choices=perm_choices))]

Проблема
Создание новых фрагментов работает нормально, но редактирование существующего просто показывает пустой виджет CheckboxSelectMultiple:
Изображение


Попытки решения
Мне явно нужно заполнить форму при ее инициализации. В идеале использовать встроенный виджет CheckboxSelectMultiple. Для этого я попытался определить следующую форму:

Код: Выделить всё

@register_snippet
class Permission(models.Model):
# ...

# Custom form subclass for snippets per documentation
# https://docs.wagtail.org/en/v2.15/advanced_topics/customisation/page_editing_interface.html
class Permission(WagtailAdminModelForm):
p = forms.IntegerField(
widget=forms.CheckboxSelectMultiple(
choices=perm_choices,
),
label="Permission field",
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['p'].initial = {
k.name for k in [Perm.Read, Perm.Write] if k.value in Perm(int(p))
}

def clean_selected_permissions(self):
selected_p = self.cleaned_data["p"]
value = Perm.Empty
for k in selected_p:
value |= Perm.__members__[k]
return value

class Meta:
model=Permission
fields=["perm"]

# Models not defined yet error here!
Permission.base_form_class = PermissionForm
Однако я не могу заставить эту форму работать. Существует цикл, в котором PermissionForm требует определения Permission или наоборот. Использование назначения формы глобальной модели, как показано здесь Gasman, мне не помогло. Мне также интересно, есть ли более простой подход к решению проблемы, с которой я столкнулся, но которого я просто не вижу.

Похожие вопросы, которых не было. Я не могу решить мою проблему
  • Вопрос: заполнить CheckboxSelectMultiple существующими данными из формы модели django

    Комментарий: OP реализует специальную ModelForm, которая связывает CheckBoxSelectMultiple вплоть до models.ManyToManyField. Это работает, поскольку тип ManyToManyField автоматически совместим с виджетом. В моем случае мне приходится настраивать его самому.
[*]Вопрос: Начальные значения для CheckboxSelectMultiple
  • Комментарий: OP использует MultiSubscriptionForm, который сам содержит аргумент ключевого слова для заполнения существующих полей. В моей ситуации этого не существует.
[*]Вопрос: Переопределение шаблона администратора Django: отображение checkboxselectmultiple виджет
  • Комментарий: ОП описывает структуру таблицы и спрашивает, возможно ли это. Отсутствие ответа решает проблему (возможно, плохо сформулированный вопрос)
[*]Вопрос: Django - Отображение виджета CheckboxSelectMultiple() индивидуально в шаблоне (вручную)
  • Комментарий: ОП хочет настроить шаблон CheckboxSelectMultiple, чтобы отображать специальная договоренность. В ответах для этого предоставляется HTML-шаблон, но в остальном они полагаются на тип/отношение поля ManyToMany, которое автоматически связывает/заполняет флажки.


Подробнее здесь: https://stackoverflow.com/questions/792 ... tail-admin
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»