Как я могу создать z3c.form, который имеет несколько схем?

Я использую cms Plone для создания формы, которая содержит две другие схемы.

С помощью групповых форм я смог включить оба поля двух схем. Однако они теряют все свои свойства, такие как скрытые или когда я использую поле данных для построения таблицы. То, что я хочу сделать, - это иметь обе эти формы с их полями и сохранять их в объекте, ссылка на который была нажата как родительский -> объект 1 [верх формы] -> объект 2 [внизу формы]

Вот мой код Python:

class QuestionPart(group.Group):
    label = u'Question Part'
    fields = field.Fields(IQuestionPart)
    template = ViewPageTemplateFile('questionpart_templates/view.pt')

 class Question(group.Group):
     label = u'Question'
     fields = field.Fields(IQuestion)
     template = ViewPageTemplateFile('question_templates/view.pt')

class QuestionSinglePart(group.GroupForm, form.AddForm):
    grok.name('register')
    grok.require('zope2.View')
    grok.context(ISiteRoot)
    label = u"Question with Single Part"

    ignoreContext = True
    enable_form_tabbing  = False

    groups = (Question,QuestionPart)

def update(self):
    super(QuestionSinglePart, self).update()

Этот код отображает оба поля IQuestion, IQuestionPart без учета таких вещей, как: form.mode(contype='hidden') или виджет DataGridField. Я нашел способ, который отображает правильную форму с подсказками поля.

class QuestionSinglePart(AutoExtensibleForm, form.AddForm):
    grok.require('zope2.View')
    grok.context(ISiteRoot)

    label = u"Question"
    schema = IQuestion
    additionalSchemata = (IQuestionPart,)                             

Я чувствую, что мне еще далеко. Я разговаривал с некоторыми людьми. Я сейчас пытаюсь использовать отдельную форму и вид.

На данный момент, я нахожусь на этом этапе с моим кодом:

class QuestionSinglePartForm(AutoExtensibleForm, form.Form):

    ignoreContext = True

    autoGroups = True
    template = ViewPageTemplateFile('questionsinglepart_templates/questionsinglepartform.pt')

    @property
    def additionalSchemata(self):
        return self._additionalSchemata

    def __init__(self, context, request, schema, additional=()):
        self.context = context
        self.request = request
        if not IInterface.providedBy(schema):
            raise ValueError('Schema is not interface object')
        self._schema = schema
        if not all(IInterface.providedBy(s) for s in additional):
            raise ValueError('Additional schema is not interface')
        self._additionalSchemata = additional

class QuestionSinglePartView(object):

    schema = IQuestion
    additional = (IQuestionPart,)

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.form = QuestionSinglePartForm(context, request, self.schema, self.additional)

    def magic(self, data, errors):
        pass
        """
        question = Question()
        question.number = data['number']
        question.questionContent = data['questionContent']

        questionPart = QuestionPart()
        questionPart.typeOfQuestion = data['IQuestionPart.typeOfQuestion']
        questionPart.explanation = data['IQuestionPart.explanation'] 
        questionPart.fileSize = data['IQuestionPart.fileSize']
        questionPart.fileType = data['IQuestionPart.fileType']
        questionPart.hints = data['IQuestionPart.hints']
        questionPart.table = data['IQuestionPart.table']
        questionPart.contype = data['IQuestionPart.contype']
        questionPart.content = data['IQuestionPart.content']
        """

    def update(self, *args, **kwargs):
        if self.request.get('REQUEST_METHOD') == 'POST':
            data, errors = self.form.extractData()
            self.magic(data, errors)
        self.formdisplay = self.form.render()

    def __call__(self, *args, **kwargs):
        self.update(*args, **kwargs)
        return self.index(*args, **kwargs)

Я борюсь с визуализацией формы и тем, что у объекта QuestionSinglePart нет атрибута индекса.

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

Я пропустил:

    @property
    def schema(self):
        return self._schema

Мне нужно было определить индекс в представлении так:

index = ViewPageTemplateFile('questionsinglepart_templates/questionsinglepart.pt')

Мне нужно было добавить это к представлениям init:

alsoProvides(self.form, IWrappedForm)

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

def update(self, *args, **kwargs):
    self.form.update(*args, **kwargs)
    self.formdisplay = self.form.render()

Я все еще работаю над тем, чтобы получить данные для сохранения в объекты.

2 ответа

Решение

Вот мой окончательный код с изменениями, сделанными выше. Были проблемы с индексом для объекта. Мне нужно было создать простой пользовательский вид. Я забыл свойство для схемы в форме. Мне нужно изменить свой метод обновления для представления, а также.

class QuestionSinglePartForm(AutoExtensibleForm, form.Form):

    ignoreContext = True

    autoGroups = False

    @property
    def schema(self):
        return self._schema

    @property
    def additionalSchemata(self):
        return self._additionalSchemata

    def __init__(self, context, request, schema, additional=()):
        self.context = context
        self.request = request
        if not IInterface.providedBy(schema):
            raise ValueError('Schema is not interface object')
        self._schema = schema
        if not all(IInterface.providedBy(s) for s in additional):
            raise ValueError('Additional schema is not interface')
        self._additionalSchemata = additional

    @button.buttonAndHandler(u'Save')
    def handleSave(self, action):
        data, errors = self.extractData()
        if errors:
            return False
        obj = self.createAndAdd(data)
        if obj is not None:
            # mark only as finished if we get the new object
            self._finishedAdd = True
            IStatusMessage(self.request).addStatusMessage(_(u"Changes saved"), "info")
        print data

    @button.buttonAndHandler(u'Cancel')
    def handleCancel(self, action):
        print 'cancel'



class QuestionSinglePartView(object):

    schema = IQuestion
    additional = (IQuestionPart,)
    index = ViewPageTemplateFile('questionsinglepart_templates/questionsinglepart.pt')

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.form = QuestionSinglePartForm(context, request, self.schema, self.additional)
        alsoProvides(self.form, IWrappedForm)

    def magic(self, data, errors):
        pass
        """
        question = Question()
        question.number = data['number']
        question.questionContent = data['questionContent']

        questionPart = QuestionPart()
        questionPart.typeOfQuestion = data['IQuestionPart.typeOfQuestion']
        questionPart.explanation = data['IQuestionPart.explanation'] 
        questionPart.fileSize = data['IQuestionPart.fileSize']
        questionPart.fileType = data['IQuestionPart.fileType']
        questionPart.hints = data['IQuestionPart.hints']
        questionPart.table = data['IQuestionPart.table']
        questionPart.contype = data['IQuestionPart.contype']
        questionPart.content = data['IQuestionPart.content']
        """

    def update(self, *args, **kwargs):
        self.form.update(*args, **kwargs)
        self.formdisplay = self.form.render()

    def __call__(self, *args, **kwargs):
        self.update(*args, **kwargs)
        return self.index(*args, **kwargs)

Только классы формы, которые включают plone.autoform.base.AutoExtensibleForm mixin обратите внимание на схему подсказок формы. Попробуйте использовать это как дополнение к классу формы вашей группы (и предоставьте schema атрибут, который ищет этот миксин вместо fields):

from plone.autoform.base import AutoExtensibleForm

class QuestionPart(AutoExtensibleForm, group.Group):
    label = u'Question Part'
    schema = IQuestionPart
    template = ViewPageTemplateFile('questionpart_templates/view.pt')
Другие вопросы по тегам