在一个页面中使用两个视图处理多个Django表单的正确方法?

时间:2014-07-31 17:37:01

标签: django django-forms django-templates django-views

过去两天我一直在努力解决这个问题,并且可以使用一些帮助。我的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>

如果用户提交了sign_in表单,他们将被带到可以查看其他网站成员的页面。如果他们提交了sign_up表单,他们将被带到第二个注册页面,在那里他们将创建用户个人资料等。

最初,我打算使用此question中显示的技术并使用一个视图来处理主页。但是,我决定尝试使用两个视图,因为我使用了Django的实际登录视图(django.contrib.auth.views.login),以便我可以添加代码来检测用户&# 39; s设备(手机,平板电脑或计算机),并将该视图与我的sign_up视图合并将创建一个非常长且复杂的视图来维护。我希望将两种表单的视图分开。

这是主页和sign_in视图:

# 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

注册视图将是您处理表单的典型,基于函数的视图,如Django documentation中所述。

我挣扎的是我的URLconf文件。这是我的主要和#34;家庭&#34; 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'),
)

问题是我在模板渲染过程中遇到此错误:

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']

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

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

但我已经在主URLconf中显示了模板名称。而且我认为我不需要在表单操作中传递其他视图参数(例如redirect_field_name),因为它们是可选的。无论如何,将此参数添加到表单操作并没有解决它。

令我困惑的一件事是如何设置第一个url参数。我已将它们设置为r&#39; ^ sign_in / $&#39;和r&#39; ^ sign_up / $&#39;因为如果我将它们都设置为r&#39; ^ $&#39;,页面将正确呈现,但是当我提交任何一个表单时,它只会回发到主页。你可以通过做一个&#34;查看源&#34;来看到这种情况。在页面上。它表明每个表格的行动都是&#34; /&#34;。另一方面,我现在拥有它的方式对我来说似乎不正确,因为该网站实际上没有&#34; / sign_in /&#34;和&#34; / sign_up /&#34; URL,因为两个表单都在主页上。此外,是否存在一个问题,如果用户提交一个或另一个不正确,两个表单的错误将在页面上呈现?

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

感谢。

2 个答案:

答案 0 :(得分:1)

您的表单名称是&#39; sign_in_form&#39;并且&#39; sign_up_form&#39;,但是在你的html中,你写了&#39; form.as_p&#39;而不是&#39; sign_in_form.as_p&#39;和&#39; sign_up_form.as_p&#39;这是您在代码中看到的第一个错误。

真正的问题在于您的网址配置。在你的主urls.py中你有

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

虽然你无法访问localhost:8000 / sign_in /因为最初它不满足 ^ $

尝试通过

进行更改
url(r'', include('apps.home.urls')),

并将其放在urls.py的末尾。

答案 1 :(得分:0)

我测试一下,看看这是否是你想要的: 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中:

            <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 %}