2012-04-05 1 views
5

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

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

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

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

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

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

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

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

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

Код класса wizardview в views.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/') 

ответ

1

Давайте посмотрим, если я могу помочь. Я сделал мастер формы, который добавляет шаги в зависимости от ответов.На каждом шаге я сохраняю все формы в переменной сеанса, например так:

def process_step(self, request, form, step): 
    request.session['form_list'] = self.form_list 
    request.session['initial'] = self.initial 

Затем каждый раз, когда смотреть оказывается, я экземпляр нового мастера форм со всеми предыдущими данными:

def dynamic_wizard(request): 
    if not request.session.get('form_list'): 
     form = Wizard([Form1]) 
    else: 
     form = Wizard(request.session.get('form_list'), initial = request.session['initial']) 
    return form(context=RequestContext(request), request=request) 
+0

Это было django 1.3. – daigorocub

2

Для будущих googlers:

У меня был некоторый успех с использованием get_form(), потому что он вызывается перед визуализацией формы. Начните с парой ModelForms:

class Wizard1(models.ModelForm): 
    class Meta: 
     model = MyModel 
     fields = ('field0', 'model0') 
class Wizard2(models.ModelForm): 
    class Meta: 
     model = MyModel 
     excludes = ('field0', 'model0') 

Тогда в вашем SessionWizardView:

class MyWizard(SessionWizardView): 
    def get_form(self, step=None, data=None, files=None): 
     form = super(ExtensionCreationWizard, self).get_form(step, data, files) 

     if step is not None and data is not None: 
      # get_form is called for validation by get_cleaned_data_for_step() 
      return form 

     if step == "0": 
      # you can set initial values or tweak fields here 

     elif step == "1": 
      data = self.get_cleaned_data_for_step('0') 
      if data is not None: 
       form.fields['field1'].initial = data.get('field0') 
       form.fields['field2'].widget.attrs['readonly'] = True 
       form.fields['field3'].widget.attrs['disabled'] = True 
       form.fields['model1'].queryset = Model1.objects.filter(name="foo") 

     return form 

Действие все в шаге 1. Вы запрашиваете данные проверены с шага 0 (который запускает еще один вызов get_form () для шага 0, поэтому будьте осторожны), а затем вы можете получить доступ к любым значениям, которые были установлены на этапе 0.

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

+0

Это способ сделать это! – JeffC

+0

hmm, метод get_form, к сожалению, здесь, к сожалению, здесь, на мой взгляд, так как любые связанные с формой вещи должны храниться в классе класса. Лучше всего использовать get_form_kwargs для установки «flags», а затем использовать их для настройки полей внутри метода init. – mariodev

 Смежные вопросы

  • Нет связанных вопросов^_^