Обработка нескольких форм на одной странице - PullRequest
0 голосов
/ 07 июня 2011

У меня есть страница учетной записи, где у меня есть три формы. Пользователь может изменить свое имя, адрес электронной почты и пароль.

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

1) информация request.user не обновляется соответствующим образом (например, она будет отставать на одно изменение или будет обновляться, если форма не подтверждена)

2) У меня есть три отдельные формы, однако, когда я отправляю одну форму, я получаю сообщения проверки из другой формы. Например, если я отправлю форму «Изменить имя», я получу 'This field is required из полей пароля в форме пароля. Вот что у меня сейчас есть -

в формах:

# in forms.py
from django.contrib.auth.models import User

class ChangeNameForm(ModelForm):
    first_name = forms.CharField(required=True)
    last_name = forms.CharField(required=True)
    class Meta:
        model = User
        fields = ('first_name', 'last_name' )

class ChangeEmailForm(ModelForm):
    email = forms.EmailField(required=True)
    class Meta:
        model = User
        fields = ('email',)

просмотров:

@login_required
def account(request):
    name_message = password_message = email_message = ''
    change_name_form = ChangeNameForm(data=request.POST or None, instance=request.user)
    change_password_form = PasswordChangeForm(data=request.POST or None, user = request.user)
    change_email_form = ChangeEmailForm(data=request.POST or None, instance=request.user)
    if request.method == "POST":
        if "change_name" in request.POST and change_name_form.is_valid():
            change_name_form.save()
            name_message = 'Your name has been changed.'
        if "change_password" in request.POST and change_password_form.is_valid():
            change_password_form.save()        
            password_message = 'Your password has been changed.'
        if "change_email" in request.POST and change_email_form.is_valid():
            ...
            email_message = 'Please click the link in your email to confirm changes.'
    return render_to_response('userprofile/account.html', 
                       {'change_name_form': change_name_form,
                        'change_email_form': change_email_form, 
                        'change_password_form': change_password_form,
                        'password_message': password_message,
                        'name_message': name_message,
                        'email_message': email_message,}, 
                        context_instance=RequestContext(request))

в шаблоне:

<h3>Change Name</h3>
    <form method="post" action="/account/change/" name='name'> {% csrf_token %}
        <h4>Change name: {{user.first_name}} {{user.last_name}}</h4>
        <table>{{change_name_form.as_table}}</table>
        <p>{{name_message}}</p>
        <p><input type="submit" value="Save Changes" name="change_name"/></p>
    </form>

<h3>Change Email</h3>
    <form method="post" action="/account/change/" name='email'> {% csrf_token %}
        <h4>Change email: {{user.email}}</h4>
        <table>{{change_email_form.as_table}}</table>
        <p>{{email_message}}</p>
        <p><input type="submit" value="Save Changes" name="change_email" /></p>
    </form>

<h3>Change Password</h3>
    <form method="post" action="/account/change/" name='password'> {% csrf_token %}
        <h4>Change password</h4>
        <table>{{change_password_form.as_table}}</table>
        <p>{{password_message}}</p>
        <p><input type="submit" value="Save Changes" name="change_password"/></p>
    </form>

Что мне нужно сделать, чтобы решить две проблемы: убедиться, что информация request.user актуальна, и убедиться, что проверка выполняется только для текущей формы? Кроме того, возможно ли запустить for loop для уменьшения избыточности в коде шаблона? Если так, как бы я это сделал, учитывая тот факт, что два поля name ?. Спасибо.

Ответы [ 2 ]

2 голосов
/ 08 июня 2011

Я думаю, что Мартин означает:

@login_required
def account(request):
    name_message = password_message = email_message = ''
    if request.method == "POST":
       change_name_form = ChangeNameForm(data=request.POST or None, instance=request.user)
       change_password_form = PasswordChangeForm(data=request.POST or None, user = request.user)
       change_email_form = ChangeEmailForm(data=request.POST or None, instance=request.user)
       ...
   else:
       change_name_form = ChangeNameForm(instance=request.user)
       change_password_form = PasswordChangeForm(instance = request.user)
       change_email_form = ChangeEmailForm(instance=request.user)
   ...
   return render_to_response('userprofile/account.html', 
                   {'change_name_form': change_name_form,
                    'change_email_form': change_email_form, 
                    'change_password_form': change_password_form,
                    'password_message': password_message,
                    'name_message': name_message,
                    'email_message': email_message,}, 
                    context_instance=RequestContext(request))

Если запрос к этому представлению является POST (то есть пользователь пытается отредактировать свою учетную запись), вы создаете экземпляр формы с атрибутами POST запроса. Если они только приходят на страницу редактирования, но еще не выполнили редактирование (то есть они еще не добавляли POST-формы), просто создайте экземпляры форм с данными из базы данных

1 голос
/ 07 июня 2011

Чтобы ответить на ваш второй вопрос, вы создаете все 3 формы с данными POSTd, даже если эта конкретная форма не была вызвана. Это вызовет проверку на всех 3 формах. Я бы переместил создание формы вниз в операторы if, которые у вас есть ниже, где вы проверяете наличие соответствующей кнопки submit.

...