Получить ранее введенную информацию в Django FormWizard - PullRequest
7 голосов
/ 07 августа 2009

Я пытаюсь создать простую многостраничную форму Django, используя FormWizard. Форма должна делать следующее:

  1. Позвольте посетителю ввести имя и фамилию в форме.
  2. Перейдите на следующую страницу, где будут отображаться введенные ранее имя и фамилия, на этой странице также будет поле, позволяющее посетителю ввести сообщение.
  3. Посетитель перейдет на страницу Django done.html, где будет храниться и отображаться вся информация.

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

forms.py

from django import forms
from django.shortcuts import render_to_response
from django.contrib.formtools.wizard import FormWizard

class ContactWizard(FormWizard):
    def done(self, request, form_list):
        return render_to_response('done.html', {
            'form_data': [form.cleaned_data for form in form_list],
        })

    def get_template(self, step):
        return 'buydomain/templates/reg%s.html' % step

class Form1(forms.Form):
    firstName = forms.CharField()
    lastName = forms.CharField()

class Form2(forms.Form):
    message = forms.CharField(widget=forms.Textarea)

шаблон для шага 1:

{% block content %}
<p>Step {{ step }} of {{ step_count }}</p>
<form action="." method="post">
<table>
{{ form }}
</table>
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
{{ previous_fields|safe }}
<input type="submit">
</form>
{% endblock %}

шаблон для шага 2:

{% block content %}
<p>Step {{ step }} of {{ step_count }}</p>


{% comment %}
Show values entered into Form1 here !
{% endcomment %}

<form action="." method="post">
<table>
{{ form }}
</table>
<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
{{ previous_fields|safe }}
<input type="submit">
</form>
{% endblock %}

Я прошу прощения, если мне немного неясно, чего я хочу достичь, и я надеюсь, что кто-то предложит решение. Заранее спасибо.

Ответы [ 3 ]

6 голосов
/ 30 октября 2009

Сначала несколько общих советов - если вы не понимаете, как использовать что-то в Django, вытащите этот текстовый редактор и посмотрите на код. Это не всегда самый быстрый способ получить ответ, но я полагаю, что он приносит дивиденды в долгосрочной перспективе.

Попробуйте добавить extra_context ко второму шагу, переопределив process_step в своем подклассе FormWizard. Вот комментарии из FormWizard (django 1.1):

 def process_step(self, request, form, step):
        """
        Hook for modifying the FormWizard's internal state, given a fully
        validated Form object. The Form is guaranteed to have clean, valid
        data.

        This method should *not* modify any of that data. Rather, it might want
        to set self.extra_context or dynamically alter self.form_list, based on
        previously submitted forms.

        Note that this method is called every time a page is rendered for *all*
        submitted steps.
        """
        pass

так что в вашем собственном классе ContactWizard, что-то вроде (NB: я не запускал это):

class ContactWizard(FormWizard):
    def process_step(self,request,form,step):
        if step == 1:
            self.extra_context = {'whatever': form.whatever_you_want_from_the_form}
            return
        else:
            return
4 голосов
/ 22 октября 2012

Ответ Тоби Панцера не позволяет классу формы получить доступ к дополнительным контекстным данным - только шаблон, на котором отображается форма, имеет доступ. Тем не менее, звучит так, как будто это то, что вам нужно. Однако, если вам нужна форма для доступа, я решил это путем переопределения get_form_kwargs. Обычно он просто возвращает пустой словарь, который заполняет get_form, поэтому переопределив его, чтобы вернуть словарь с предварительно заполненными данными, вы можете передать kwargs в форму init.

def get_form_kwargs(self, step=None):
    kwargs = {}
    if step == '1':
        your_data = self.get_cleaned_data_for_step('0')['your_data']
        kwargs.update({'your_data': your_data,})
    return kwargs

Затем в вашей форме init метод вы можете просто вытолкнуть kwarg перед вызовом super:

self.your_data = kwargs.pop('client', None)
3 голосов
/ 16 февраля 2010

Не знаю, полезно ли еще публиковать это решение. Тем не менее. Необходимые вещи между различными формами (шагами), используемыми Волшебником, легко доступны, когда вы даете волшебнику дополнительный атрибут в форме диктата. Вот так:

class WizardRegistration(FormWizard):
    def __init__(self, *args, **kwargs):
        super(WizardRegistration, self).__init__(*args, **kwargs)

        setattr(self, 'chosen', {})

Между шагами вы можете легко взять форму или материал модели и сохранить его, пока не достигнете метода done (). Сохранить значение формы

self.chosen['something_to_store'] = form.cleaned_data.get('a_form_value')

Или даже получить / изменить / сохранить модель:

object = Model.objects.get('some_query')

if self.chosen['object']:
    self.chosen['object'].string = 'Something stringy'
    self.chosen['object'].save()
...