Требуется разъяснение по использованию мастеров форм Django 1.4, особенно по предварительному заполнению и сохранению.

Мы создаем мастер, используя новые функции мастера форм Django 1.4.
Документы по этому вопросу очень кратки, и мы не можем найти каких-либо сложных примеров. Мы используем мастер именованных шагов (необходим для поддержки используемого нами представления списка/сетки данных) и серверную часть сеанса. Мастер предназначен для редактирования ролей и связанных прав и обеспечивает функции добавления и редактирования. Мы делаем это, спрашивая пользователя на первом этапе, хочет ли он/она добавить или отредактировать.

Следующий шаг зависит от этого выбора; Если пользователь хочет внести изменения, появляется экран поиска, за которым следует список/таблица данных, в котором отображаются результаты. Затем пользователь может выбрать один из результатов и перейти к экрану сведений, а затем к странице FilteredSelectMultiple, позволяющей ему/ей связать права с этой ролью.

Если пользователь хочет добавить новую роль, экраны поиска и результатов пропускаются, и пользователь переходит непосредственно к экрану сведений, а затем к экрану ссылок.
Все это работает очень хорошо, используя condition_dictв URL-адресах.py, но нам интересно несколько вещей, касающихся общей функциональности:

Когда выбрана конкретная ранее существовавшая роль, как мы можем заполнить детали и экран ссылок соответствующими данными?

Создаем ли мы экземпляр объекта-роли и передаем ли его как-то двум формам, если да, то где мы его создаем и нужно ли нам делать это для каждой формы отдельно (что кажется несколько чрезмерным)?

При сохранении обычной практикой является создание другого экземпляра объекта роли, добавление к нему данных формы и сохранение, или мы можем каким-то образом повторно использовать объект, используемый в формах?

Мы попытались перегрузить get_form_instanceдля возврата экземпляров ролей, и мы рассмотрели instance_dictв документации, но нам кажется, что это неправильный подход, и примеров для примера нет. найдены в Интернете, и мы даже не уверены, что они используются для предварительного заполнения данных или даже если мы на правильном пути.

Логически я бы сказал, что на шаге выбора существующей роли мне нужно заполнить переменные мастера, используя экземпляр выбранного объекта, и они отобразятся в формах. В конце мастера мы обращаем процесс и получаем все данные из переменных мастера, добавляем их во вновь созданный объект ролей и сохраняем его. В идеале этот экземпляр сам определяет, нужно ли ему выполнять INSERT или UPDATE, в зависимости от того, заполнен ли первичный ключ.

Если кто-нибудь может привести пример или подтолкнуть в правильном направлении, мы будем очень признательны.

Код класса wizardview в представлениях.py ниже:

class RolesWizard(NamedUrlSessionWizardView):

def get_template_names(self):
    # get template for each step...
    if self.steps.current == 'choice':
        return 'clubassistant/wizard_neworeditrole.html'
    if self.steps.current == 'search':
        return 'clubassistant/wizard_searchrole.html'
    if self.steps.current == 'results':
        return 'clubassistant/wizard_pickrole.html'
    if self.steps.current == 'details':
        return 'clubassistant/wizard_detailsrole.html'
    elif self.steps.current == 'rights':
        return 'clubassistant/wizard_roles.html'

def get_context_data(self, form, **kwargs):
    # get context data to be passed to the respective templates
    context = super(RolesWizard, self).get_context_data(form=form, **kwargs)

    # add the listview in the results screen
    if self.steps.current == 'results':
        # get search text from previous step
        cleaned_data = self.get_cleaned_data_for_step('search')
        table = RolesTable(Roles.objects.filter(
            role_name__contains=cleaned_data['searchrole'])
        )
        RequestConfig(self.request, paginate={
            "per_page": 4,
            }).configure(table)
        # add the listview with results
        context.update({'table': table})

    # add a role instance based on the chosen primary key
    if self.steps.current == 'rights':
        cleaned_data = self.get_cleaned_data_for_step('results')
        role_id = cleaned_data['role_uuid']
        role = get_object_or_404(Roles, pk=role_id)
        context.update({'role': role})

    return context

def done(self, form_list, **kwargs):
    # this code is executed when the wizard needs to be completed

    # combine all forms into a single dictionary
    wizard = self.get_all_cleaned_data()

    if wizard.get("neworeditrole")=="add":
        role = Roles()
    else:
        role = get_object_or_404(Roles, pk=wizard.get("role_uuid"))

    # many-to-many rights/roles
    role.role_rights_new_style.clear()
    for each_right in wizard.get('role_rights_new_style'):
        RightsRoles.objects.create(role=role, right=each_right,)

    # other properties
    for field, value in self.get_cleaned_data_for_step('details'):
        setattr(role, field, value)

    role.save()

    # return to first page of wizard...
    return HttpResponseRedirect('/login/maintenance/roles/wizard/choice/')

5
задан Erik Oosterwaal 5 April 2012 в 13:53
поделиться