Skip to content

Commit ca8001f

Browse files
committed
Adding support for user login
Implementing the templates/views required to make use of Django's inbuilt user functions for login/reset etc. Requires email details to be setup in settings.py in order to properly test-drive.
1 parent 246a18d commit ca8001f

File tree

14 files changed

+685
-6
lines changed

14 files changed

+685
-6
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.pyc
2+
*~
3+
.DS_Store
4+
static*

control/rotarise/auth/__init__.py

Whitespace-only changes.

control/rotarise/auth/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.db import models
2+
3+
# Create your models here.

control/rotarise/auth/tests.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
This file demonstrates writing tests using the unittest module. These will pass
3+
when you run "manage.py test".
4+
5+
Replace this with more appropriate tests for your application.
6+
"""
7+
8+
from django.test import TestCase
9+
10+
11+
class SimpleTest(TestCase):
12+
def test_basic_addition(self):
13+
"""
14+
Tests that 1 + 1 always equals 2.
15+
"""
16+
self.assertEqual(1 + 1, 2)

control/rotarise/auth/views.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
from django import forms
2+
from django.http import HttpResponse, HttpResponseRedirect
3+
from django.shortcuts import render_to_response
4+
from django.contrib.auth.models import User
5+
from django.contrib.auth.views import password_reset
6+
from django.core.context_processors import csrf
7+
from django.contrib.auth import authenticate, login as login_user, logout as logout_user
8+
from django.template import RequestContext
9+
10+
INVALID_PASSWORD = "1"
11+
NO_ERROR = "0"
12+
13+
14+
#Template defnitions
15+
REGISTRATION_TEMPLATE = 'auth/register.html'
16+
LOGIN_TEMPLATE = 'auth/login.html'
17+
18+
#Defining forms. Django will take this definition and produce a form which can
19+
#then be picked up by one of the django templates and customised.
20+
class RegistrationForm(forms.Form):
21+
firstname = forms.CharField(max_length=100)
22+
surname = forms.CharField()
23+
password = forms.CharField(label=(u'Password'),widget=forms.PasswordInput(render_value=False))
24+
email = forms.EmailField()
25+
#Fields left out of the form until we know what is wanted for a signup.
26+
#Address Details
27+
#house = forms.CharField()
28+
#addrline1 = forms.CharField()
29+
#addrline2 = forms.CharField()
30+
#country = forms.CharField()
31+
#postcode = forms.CharField()
32+
33+
class ResetPasswordForm(forms.Form):
34+
email = forms.EmailField()
35+
36+
class LoginForm(forms.Form):
37+
username = forms.CharField(max_length=100)
38+
password = forms.CharField(label=(u'Password'),widget=forms.PasswordInput(render_value=False))
39+
40+
41+
######## Helper Functions ######################################################
42+
43+
def generate_username(fname, sname):
44+
return "%s.%s" % (fname, sname)
45+
46+
47+
######## Request Functions ####################################################
48+
49+
def register(request):
50+
c = {}
51+
c.update(csrf(request))
52+
context_inst = RequestContext(request)
53+
if request.method == 'POST':
54+
#Handle form submission
55+
form = RegistrationForm(request.POST)
56+
if form.is_valid():
57+
firstname = form.cleaned_data['firstname']
58+
surname = form.cleaned_data['surname']
59+
password = form.cleaned_data['password']
60+
email = form.cleaned_data['email']
61+
try:
62+
#Check if someone has already used that email
63+
#address. The email is the username as well,
64+
#and so has to be unique.
65+
if User.objects.get(email__exact=email):
66+
c['error'] = 'ALREADY_SIGNED_UP'
67+
c['error_value'] = email
68+
c['form'] = RegistrationForm()
69+
return render_to_response(REGISTRATION_TEMPLATE, c, context_inst)
70+
except:
71+
pass
72+
print form.cleaned_data
73+
user = User.objects.create_user(email, email, password)
74+
user.first_name = firstname
75+
user.last_name = surname
76+
user.save()
77+
return render_to_response('thanks.html', c, context_inst)
78+
79+
else:
80+
#First time visiting, return an empty form for filling in
81+
form = RegistrationForm()
82+
c['form'] = form
83+
return render_to_response(REGISTRATION_TEMPLATE, c)
84+
85+
86+
def login(request, code=NO_ERROR):
87+
context_inst = RequestContext(request)
88+
redirect = request.GET.get('next', '')
89+
c = {}
90+
c.update(csrf(request))
91+
#Check for the invalid password error code
92+
if code == INVALID_PASSWORD:
93+
#Reload the login form pass the invalid_password variable to
94+
#indicate to the user that the login has failed.
95+
form = LoginForm()
96+
c['form'] = form
97+
c['invalid_password'] = True
98+
return render_to_response(LOGIN_TEMPLATE, c, context_instance=context_inst)
99+
100+
if request.user.is_authenticated():
101+
return HttpResponseRedirect('/main/')
102+
103+
#Handle submitting username & password
104+
if request.method == 'POST':
105+
form = LoginForm(request.POST)
106+
if form.is_valid():
107+
user_text = form.cleaned_data['username']
108+
pass_text = form.cleaned_data['password']
109+
user = authenticate(username=user_text, password=pass_text)
110+
if not user:
111+
return HttpResponseRedirect('/login/%s/' % INVALID_PASSWORD)
112+
#Login the user
113+
login_user(request, user)
114+
115+
#Get Redirect - the user may have navigated to a page that required
116+
#authentication, we want to log them in, and then pass them on their way.
117+
redirect = request.POST.get('next')
118+
119+
if redirect != '':
120+
return HttpResponseRedirect(redirect)
121+
else:
122+
#Default location to send the user is to the main page.
123+
return HttpResponseRedirect('/main/')
124+
else:
125+
form = LoginForm()
126+
c['form'] = form
127+
c['next'] = redirect
128+
return render_to_response(LOGIN_TEMPLATE, c, context_instance=context_inst)
129+
130+
def reset_password(request):
131+
return password_reset(request, template_name='account_reset.html')
132+
133+
def logout(request):
134+
logout_user(request)
135+
return HttpResponseRedirect('/main/')
136+
137+
def main(request):
138+
#For the moment, make sure the user is authenticated,
139+
#and just send them to the static dashboard page.
140+
c = RequestContext(request, {'user': request.user})
141+
if not request.user.is_authenticated():
142+
return HttpResponseRedirect('/login/')
143+
return render_to_response('dashboard.html', c)
144+
145+
146+

control/rotarise/rotas/__init__.py

Whitespace-only changes.

control/rotarise/rotas/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.db import models
2+
3+
# Create your models here.

control/rotarise/rotas/tests.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
This file demonstrates writing tests using the unittest module. These will pass
3+
when you run "manage.py test".
4+
5+
Replace this with more appropriate tests for your application.
6+
"""
7+
8+
from django.test import TestCase
9+
10+
11+
class SimpleTest(TestCase):
12+
def test_basic_addition(self):
13+
"""
14+
Tests that 1 + 1 always equals 2.
15+
"""
16+
self.assertEqual(1 + 1, 2)

control/rotarise/rotas/views.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Create your views here.

control/rotarise/settings.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Django settings for rotarise project.
22

3+
import os
4+
import sys
5+
36
DEBUG = True
47
TEMPLATE_DEBUG = DEBUG
58

@@ -11,9 +14,9 @@
1114

1215
DATABASES = {
1316
'default': {
14-
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
15-
'NAME': '', # Or path to database file if using sqlite3.
16-
'USER': '', # Not used with sqlite3.
17+
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
18+
'NAME': 'rotarise', # Or path to database file if using sqlite3.
19+
'USER': 'root', # Not used with sqlite3.
1720
'PASSWORD': '', # Not used with sqlite3.
1821
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
1922
'PORT': '', # Set to empty string for default. Not used with sqlite3.
@@ -59,7 +62,7 @@
5962
# Don't put anything in this directory yourself; store your static files
6063
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
6164
# Example: "/home/media/media.lawrence.com/static/"
62-
STATIC_ROOT = ''
65+
STATIC_ROOT = '/Users/rob/django/static'
6366

6467
# URL prefix for static files.
6568
# Example: "http://media.lawrence.com/static/"
@@ -70,14 +73,15 @@
7073
# Put strings here, like "/home/html/static" or "C:/www/django/static".
7174
# Always use forward slashes, even on Windows.
7275
# Don't forget to use absolute paths, not relative paths.
76+
'/Users/rob/github/local/rotarise/static',
7377
)
7478

7579
# List of finder classes that know how to find static files in
7680
# various locations.
7781
STATICFILES_FINDERS = (
7882
'django.contrib.staticfiles.finders.FileSystemFinder',
7983
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
80-
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
84+
'django.contrib.staticfiles.finders.DefaultStorageFinder',
8185
)
8286

8387
# Make this unique, and don't share it with anybody.
@@ -106,18 +110,27 @@
106110
WSGI_APPLICATION = 'rotarise.wsgi.application'
107111

108112
TEMPLATE_DIRS = (
113+
'/Users/rob/github/local/rotarise/templates',
109114
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
110115
# Always use forward slashes, even on Windows.
111116
# Don't forget to use absolute paths, not relative paths.
112117
)
113118

119+
TEMPLATE_CONTEXT_PROCESSORS = (
120+
'django.contrib.messages.context_processors.messages',
121+
'django.contrib.auth.context_processors.auth',
122+
'django.core.context_processors.request',
123+
)
124+
114125
INSTALLED_APPS = (
115126
'django.contrib.auth',
116127
'django.contrib.contenttypes',
117128
'django.contrib.sessions',
118129
'django.contrib.sites',
119130
'django.contrib.messages',
120131
'django.contrib.staticfiles',
132+
'rotarise.auth',
133+
'rotarise.rotas',
121134
# Uncomment the next line to enable the admin:
122135
# 'django.contrib.admin',
123136
# Uncomment the next line to enable admin documentation:

0 commit comments

Comments
 (0)