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>
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.
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.
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.
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']
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">
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.
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?
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?
Thanks.