在一个页面中处理多个Django表单的正确方法有两个视图? [英] Proper way to handle multiple Django forms in one page with two views?

查看:2962
本文介绍了在一个页面中处理多个Django表单的正确方法有两个视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去两天中我遇到了这个问题,可以使用一些帮助。我的Django 1.6应用程序的主页将包含两个表单,一个用户可以使用该表单登录该站点,另一个用于注册该站点(创建一个登录名):

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:

# 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表单,他们将被带到第二个注册页面,在那里他们将创建一个用户配置文件等。

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.

最初,我要使用该问题中显示的技术并使用一个视图来处理主页。但是,我决定尝试使用两个视图,因为我使用Django的实际登录视图(django.contrib.auth.views.login),以便我可以添加代码来检测用户的设备(手机,平板电脑或计算机),并将该视图与我的sign_up视图合并将创建一个非常长而复杂的视图来维护。我宁愿保留这两种形式的意见分开。

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.

这是主页和sign_in视图:

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

注册视图只是您的典型的基于函数的v iew处理一个表单,如Django 文档

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

我正在努力的是我的URLconf文件。这是我的主要和家URLconf文件:

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

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

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

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:

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

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

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.

令我困惑的一个问题是如何设置第一个url参数。我把它们设置为r'^ sign_in / $'和r'^ sign_up / $',因为如果我将它们设置为r'^ $',那么该页面将正常呈现,但是当我提交任何一个表单时,它只是发布回来到主页。您可以通过在页面上执行查看源来看到这一点。它显示每个表单的操作将是/。另一方面,我现在的方式似乎对我来说是不正确的,因为网站实际上不会有/ sign_in /和/ sign_up /的URL,因为这两种形式都在主页上。另外,是否会有一个问题,如果用户提交一个或另一个不正确,两个表单的错误将在页面上呈现?

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?

据我所知,Django文档并没有真正描述一个正在做我想做的标准方法。它描述了如何渲染相同表单的多个版本。任何人都可以告诉我我在做错什么?

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?

谢谢。

推荐答案

您的表单名称是sign_in_form和sign_up_form,但是在您的html中,您将其写入form.as_p而不是sign_in_form.as_p和sign_up_form.as_p,这是代码中看到的第一个错误。

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.

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

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

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

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

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

尝试通过

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

并把它放到最后的urls.py。

and put it to the end of urls.py.

这篇关于在一个页面中处理多个Django表单的正确方法有两个视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆