如何在一个页面中处理两个视图的多个Django表单?

[英]Proper way to handle multiple Django forms in one page with two views?


I've struggled with this problem for the last two days and could use some help. The home page for my Django 1.6 application will include two forms, one that a user can use to sign in to the site and one they can use to sign up (create a login) for the site:

过去两天我一直在努力解决这个问题,我需要一些帮助。我的Django 1.6应用程序的主页将包括两种表单,一个用户可以用来登录站点的表单,另一个可以用来注册站点(为站点创建一个登录):

# templates/home/home_page.html
<div class="sign-in-form">
    <form action="{% url 'apps.home.views.sign_in' %}" method="post">
        {% csrf_token %}

        {{ sign_in_form.as_p }}

        {% if next %}
            <input type="hidden" name="next" value="{{ next }}">
        {% else %}
            <input type="hidden" name="next" value="{% url 'view-members' %}">
        {% endif %}
        <input type="submit" value="Sign in">
    </form>
</div>

<div class="sign-up-form">
<fieldset>
    <legend>Sign up</legend>
    <form action="{% url 'apps.home.views.sign_up' %}" method="post">
        {% csrf_token %}

        {{ sign_up_form.as_p}}

        <p><input type="submit" value="Sign up" /></p>
    </form>
</fieldset>
</div>

If the user submits, the sign_in form, they'll be taken to a page where they can view other site members. If they submit the sign_up form, they'll be taken to a second signup page where they'll create a user profile, etc.

如果用户提交了sign_in表单,他们将被带到一个可以查看其他站点成员的页面。如果他们提交了注册表单,他们将被带到第二个注册页面,在那里他们将创建一个用户配置文件,等等。

Originally, I was going to use the technique shown in this question and use one view to handle the homepage. However, I decided to try to use two views because I'm using the Django's actual login view (django.contrib.auth.views.login) so that I can add code to it to detect the user's device (phone, tablet, or computer), and merging that view with my sign_up view would create a very long and complicated view to maintain. I'd prefer to keep the views for both forms separate.

最初,我打算使用问题中显示的技术,使用一个视图来处理主页。然而,我决定尝试使用两种不同的观点,因为我使用Django的实际登录视图(django.contrib.auth.views.login),这样我可以添加代码来检测用户的设备(手机、平板电脑或电脑),和合并这一观点与我sign_up视图将创建一个非常漫长而复杂的视图维护。我想把这两种形式的视图分开。

Here's the home page and sign_in views:

这是主页和登录视图:

# apps/home/views:
def home_page(request, template):
    sign_in_form = SignInAuthenticationForm()
    sign_up_form = CreateAccountForm()
    return render(request, template, {"sign_in_form": sign_in_form,
                                      "sign_up_form": sign_up_form})

@sensitive_post_parameters()
@csrf_protect
@never_cache
def sign_in(request, 
            template='home_page.html',
            redirect_field_name=REDIRECT_FIELD_NAME,
            # authentication_form=AuthenticationForm,
            authentication_form=SignInAuthenticationForm,
            current_app=None, extra_context=None):

    # Do device detection here...
    # django.contrib.auth.views code goes here...

    return response

The signup view will just be your typical, function-based view for processing a form as described in the Django documentation.

注册视图将是典型的、基于功能的视图,用于处理Django文档中描述的表单。

What I'm struggling with is my URLconf files. Here's my main and "home" URLconf files:

我在挣扎的是我的URLconf文件。这是我的主文件和“home”URLconf文件:

# conf/urls.py
urlpatterns = patterns('',
    url(r'^$',         include('apps.home.urls')),
    # Other url patterns...
)

# apps/home/urls.py
urlpatterns = patterns('apps.home.views',
    url(r'^$',
        'home_page',
        {'template': 'home/home_page.html'},
        name='home-page'),
    url(r'^sign_in/$',
        'sign_in',
        {'template': 'home/home_page.html'},
        name='sign-in'),
    url(r'^sign_up/$',
        'sign_up',
        {'template': 'home/home_page.html'},
        name='sign-up'),
)

The problem is that I get this error during template rendering:

问题是在模板渲染过程中我得到了这个错误:

NoReverseMatch at /

Reverse for 'apps.home.views.sign_in' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['$sign_in/$']

Request Method: GET
Request URL:    http://localhost:8000/
Django Version: 1.6.2
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'apps.home.views.sign_in' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['$sign_in/$']
Exception Location: /Users/smith/venv/swing/lib/python2.7/site-packages/django/core/urlresolvers.py in _reverse_with_prefix, line 429
Python Executable:  /Users/smith/venv/swing/bin/python
Python Version: 2.7.5
Python Path:    
['/Users/smith/Dropbox/www/swing',
 '/Users/smith/venv/swing/lib/python2.7/site-packages/wurfl_cloud-1.0.1-py2.7.egg',
 '/Users/smith/venv/swing/lib/python27.zip',
 '/Users/smith/venv/swing/lib/python2.7',
 '/Users/smith/venv/swing/lib/python2.7/plat-darwin',
 '/Users/smith/venv/swing/lib/python2.7/plat-mac',
 '/Users/smith/venv/swing/lib/python2.7/plat-mac/lib-scriptpackages',
 '/Users/smith/venv/swing/Extras/lib/python',
 '/Users/smith/venv/swing/lib/python2.7/lib-tk',
 '/Users/smith/venv/swing/lib/python2.7/lib-old',
 '/Users/smith/venv/swing/lib/python2.7/lib-dynload',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
 '/Users/smith/venv/swing/lib/python2.7/site-packages']

At first I started to think that maybe it's telling me that it can's find the correct URL pattern in my home/urls.py file because the URL signature in my form is incorrect. Maybe I needed to do this to match the arguments in the sign_in view:

一开始我认为它可能告诉我它可以在我的home/urls中找到正确的URL模式。py文件,因为我表单中的URL签名不正确。也许我需要这样做来匹配sign_in视图中的参数:

<form action="{% url 'apps.home.views.sign_in' 'home/home_page.html' %}" method="post">

But I'm already showing the template name in the home URLconf. And I don't think I need to pass the other view arguments in the form action (e.g. redirect_field_name) because their optional. In any case, adding this argument to the form action didn't fix it.

但是我已经在home URLconf中显示了模板名。我认为我不需要在表单操作(例如redirect_field_name)中传递其他视图参数,因为它们是可选的。在任何情况下,将这个参数添加到表单操作中都不能修复它。

One of the things that confuses me is how to set the first url argument. I've set them to r'^sign_in/$' and r'^sign_up/$' because if I set them both to r'^$', the page will render properly but when I submit either form, it justs posts back to the home page. You can see this will happen by doing a "view source" on the page. It shows each form's action will be "/". On the other hand, the way I have it now seems incorrect to me because the site won't actually have a "/sign_in/" and "/sign_up/" URL since both forms are on the home page. Also, is there going to be a problem in which if the user submits one for or the other improperly, errors for both forms will be rendered on the page?

让我困惑的是如何设置第一个url参数。我让他们r ' ^ sign_in /美元' r ' ^ sign_up /美元”,因为如果我将它们设置为r ^ $,页面将显示正确但当我提交表单,它只是职位回到主页。您可以通过在页面上执行“查看源”来实现这一点。它显示每个表单的操作将是“/”。另一方面,我现在使用的方式对我来说似乎是不正确的,因为站点实际上没有“/sign_in/”和“/sign_up/”URL,因为这两种表单都在主页上。此外,如果用户提交了一个for或另一个不正确的表单,这两个表单的错误会在页面上呈现吗?

The Django documentation, to the best of my knowledge, doesn't really describe a standard approach for doing what I'm trying to do. It describes how to render multiple versions of the same form. Can anyone tell me what I'm doing wrong?

据我所知,Django文档并没有真正描述我正在尝试做的事情的标准方法。它描述如何呈现相同表单的多个版本。有人能告诉我我做错了什么吗?

Thanks.

谢谢。

2 个解决方案

#1


1  

Your form names are 'sign_in_form' and 'sign_up_form', but in your html you wrote them 'form.as_p' instead of 'sign_in_form.as_p' and 'sign_up_form.as_p' this is the first bug a saw in your code.

您的表单名是'sign_in_form'和'sign_up_form',但是在html中您将它们写成'form '。as_p”而不是“sign_in_form。as_p’和‘sign_up_form。这是您的代码中看到的第一个错误。

The real problem is in your urls configuration. In your main urls.py you have

真正的问题在于url配置。在你的主的url。py你

 url(r'^$', include('apps.home.urls')),
 Other ...

Though you will not be able to get to localhost:8000/sign_in/ because initially it does not satisfy to ^$ .

虽然你将无法得到localhost:8000 / sign_in /因为最初它不满足^ $。

Try to change it by

试着改变它

url(r'', include('apps.home.urls')),

and put it to the end of urls.py.

然后把它放到urls.py的末端。

#2


0  

i test this see if this what you want: view.py

我测试一下,看看这是不是你想要的:view.py

def loginUser(request,**Kargs):
LoginFormSet = formset_factory(LoginForm)
SignFormSet = formset_factory(SignForm)
if request.method == 'POST':
    login_formset = LoginFormSet(request.POST, prefix='login')
    sign_formset = SignFormSet(request.POST ,prefix='sign')
    if login_formset.is_valid():
        #do somthing

    elif sign_formset.is_valid():
        #do somthing

    return render(request, 'reservetion/login.html',{'login_formset': login_formset,'sign_formset':sign_formset})

else:
    login_formset = LoginFormSet(prefix='login')
    sign_formset = SignFormSet(prefix='sign')
    return render(request, 'reservetion/login.html',{'login_formset': login_formset,'sign_formset':sign_formset})

page.html:

page.html:

            <form action="{% url 'loginUser'  %}" method="post">
                    {% csrf_token %}
{{ login_formset.management_form }}
{% for form in login_formset %}
    {{ form }}
{% endfor %}

{{ sign_formset.management_form }}
{% for form in sign_formset %}


 {{ form }}


 {% endfor %}

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2014/07/31/6f5384e1a8933d3343a989571473a558.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号