introduced django-registration for user management

pull/1/head
Ed Summers 2011-09-04 00:21:51 -04:00
parent 79f9f88213
commit 6bd5824fc4
26 changed files with 346 additions and 105 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.db *.db
*.pyc *.pyc
*.log

View File

@ -0,0 +1,10 @@
[
{
"model": "sites.site",
"pk": 1,
"fields": {
"domain": "ungluit.com",
"name": "ungluit"
}
}
]

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>unglue.it: {% block title %}{% endblock %}</title>
<link type="text/css" rel="stylesheet" href="/static/css/layout.css" />
</head>
<body>
<div id="page-wrap">
<div id="header">
<div class="main">
<div class="logo">
<a href="/"><img src="/static/images/logo.png" alt="unglue.it" title="unglue.it" /></a>
</div>
<div class="topmenu">
<ul class="menu">
{% if user.is_authenticated %}
<li class="first"><a href="{% url auth_logout %}"><span>Sign Out</span></a></li>
{% else %}
<li class="first"><a href="{% url auth_login %}"><span>Sign In</span></a></li>
{% endif %}
<li><a href="#"><span>Tour</span></a></li>
<li><a href="#"><span>FAQs</span></a></li>
<li><a href="#"><span>Help</span></a></li>
{% if not user.is_authenticated %}
<li class="last"><a href="{% url registration_register %}"><span>sign up</span></a></li>
{% endif %}
</ul>
</div>
</div>
</div>
{% block content %}{% endblock %}
</div>
</body>
</html>

View File

@ -1,38 +1,15 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> {% extends "base.html" %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>unglue.it</title>
<link type="text/css" rel="stylesheet" href="/static/css/layout.css" />
</head>
<body> {% block content %}
<div id="js-page-wrap"> <div id="topsection">
<div id="js-header"> <div class="main">
<div class="js-main"> <div class="topnews">
<div class="js-logo"> <div class="news-text">With your help we raise money to buy book rights. The unglued books are free to download, here.</div>
<a href="index.html"><img src="/static/images/logo.png" alt="unglue.it" title="unglue.it" /></a> <div class="news-links"><a class="readon"><span>Learn more</span></a></div>
</div> </div>
<div class="js-topmenu"> <div class="search">
<ul class="menu"> <div class="search-inner">
<li class="first"><a href="#"><span>Sign In</span></a></li>
<li><a href="#"><span>Tour</span></a></li>
<li><a href="#"><span>FAQs</span></a></li>
<li><a href="#"><span>Help</span></a></li>
<li class="last"><a href="#"><span>sign up</span></a></li>
</ul>
</div>
</div>
</div>
<div id="js-topsection">
<div class="js-main">
<div class="js-topnews">
<div class="js-news-text">With your help we raise money to buy book rights. The unglued books are free to download, here.</div>
<div class="js-news-links"><a class="readon"><span>Learn more</span></a></div>
</div>
<div class="js-search">
<div class="js-search-inner">
<form action=""> <form action="">
<input type="text" onfocus="if (this.value=='Search for a book...') this.value='';" onblur="if (this.value=='') this.value='Search for a book...';" value="Search for a book..." size="30" class="inputbox" maxlength="200" id="ssearchword" name="searchword"> <input type="text" onfocus="if (this.value=='Search for a book...') this.value='';" onblur="if (this.value=='') this.value='Search for a book...';" value="Search for a book..." size="30" class="inputbox" maxlength="200" id="ssearchword" name="searchword">
<input type="button" onclick="this.form.searchword.focus();" class="button" value="Search"> <input type="button" onclick="this.form.searchword.focus();" class="button" value="Search">
@ -43,8 +20,8 @@
</div> </div>
<div id="main-container"> <div id="main-container">
<div class="js-main"> <div class="main">
<div id="js-leftcol"> <div id="leftcol">
<div class="jsmodule"> <div class="jsmodule">
<h3 class="jsmod-title"><span>Explore</span></h3> <h3 class="jsmod-title"><span>Explore</span></h3>
<div class="jsmod-content"> <div class="jsmod-content">
@ -75,8 +52,8 @@
</div> </div>
</div> </div>
</div> </div>
<div id="js-maincol-fr"> <div id="maincol-fr">
<div class="js-maincol-inner"> <div class="maincol-inner">
<div class="content-block"> <div class="content-block">
<div class="content-block-heading"> <div class="content-block-heading">
<h2 class="content-heading">Currently being <span>unglued</span></h2> <h2 class="content-heading">Currently being <span>unglued</span></h2>
@ -336,9 +313,4 @@
</div> </div>
</div> </div>
{% endblock %}
</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
{% extends "registration/registration_base.html" %}
{% block title %}{% if account %}Activation complete{% else %}Activation problem{% endif %}{% endblock %}
{% block content %}
{% if account %}
Thanks {{ account }}, activation complete! You may now <a href='{% url auth_login %}'>login</a> using the username and password you set at registration.
{% else %}
Oops &ndash; it seems that your activation key is invalid. Please check the url again.
{% endif %}
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "registration/registration_base.html" %}
{% block title %}Activation complete{% endblock %}
{% block content %}
Thanks, activation complete! You may now <a href='{% url auth_login %}'>login</a> using the username and password you set at registration.
{% endblock %}

View File

@ -0,0 +1,11 @@
You (or someone pretending to be you) have asked to register an account at
{{ site.name }}. If this wasn't you, please ignore this email
and your address will be removed from our records.
To activate this account, please click the following link within the next
{{ expiration_days }} days:
http://{{site.domain}}/accounts/activate/{{ activation_key }}
Sincerely,
{{ site.name }} Management

View File

@ -0,0 +1 @@
Account registration for {{ site.name }}

View File

@ -0,0 +1,40 @@
{% extends "registration/registration_base.html" %}
{% block title %}login{% endblock %}
{% block content %}
<div id="registration">
{% if form.errors %}
<p class="errorlist">Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action="{% url django.contrib.auth.views.login %}">{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="login" /></td>
</tr>
</table>
<input type="hidden" name="next" value="{% if next %}{{ next }}{% else %}/{% endif %}" />
</form>
<br>
<br>
<br>
<br>
<p><a href="{% url auth_password_reset %}">Forgot</a> your password? <a href="{% url registration_register %}">Need an account</a>?</p>
</div>
{% endblock %}

View File

@ -0,0 +1,12 @@
{% extends "registration/registration_base.html" %}
{% block title %}Logged out{% endblock %}
{% block content %}
<script type="text/javascript">
window.location.replace("/");
</script>
<div id="registration">
Successfully logged out!
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "registration/registration_base.html" %}
{% block title %}Password changed{% endblock %}
{% block content %}
Password successfully changed!
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends "registration/registration_base.html" %}
{% block title %}Change password{% endblock %}
{% block content %}
<form method='post' action=''>{% csrf_token %}
<table>
{{ form }}
<tr><td></td><td><input type='submit' value="Change password" /></td></tr>
</table>
</form>
{% endblock %}

View File

@ -0,0 +1,7 @@
{% extends "registration/registration_base.html" %}
{% block title %}Password reset complete{% endblock %}
{% block content %}
<div id="registration">
Your password has been reset! You may now <a href="{{ login_url }}">log in</a>.
</div>
{% endblock %}

View File

@ -0,0 +1,13 @@
{% extends "registration/registration_base.html" %}
{% block title %}Confirm password reset{% endblock %}
{% block content %}
<div id="registration">
Enter your new password below to reset your password:
<form method="post" action="">{% csrf_token %}
<table>
{{ form.as_table }}
<tr><td></ td><td><input type="submit" value="Set password" /></td></tr>
</table>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends "registration/registration_base.html" %}
{% block title %}Password reset{% endblock %}
{% block content %}
<div id="registration">
<p>
We have sent you an email with a link to reset your password. Please check
your email and click the link to continue.
</p>
</div>
{% endblock %}

View File

@ -0,0 +1,16 @@
Greetings {% if user.get_full_name %}{{ user.get_full_name }}{% else %}{{ user }}{% endif %},
You are receiving this email because you (or someone pretending to be you)
requested that your password be reset on the {{ domain }} site. If you do not
wish to reset your password, please ignore this message.
To reset your password, please click the following link, or copy and paste it
into your web browser:
{{ protocol }}://{{ domain }}{% url auth_password_reset_confirm uid token %}
Your username, in case you've forgotten: {{ user.username }}
Best regards,
{{ site_name }} Management

View File

@ -0,0 +1,16 @@
{% extends "registration/registration_base.html" %}
{% block title %}Reset password{% endblock %}
{% block content %}
<div id="registration">
<p>
Forgot your password? Enter your email in the form below and we'll send you
instructions for creating a new one.
</p>
<form method='post' action=''>{% csrf_token %}
<table>
{{ form }}
<tr><td></td><td><input type='submit' value="Reset password" /></td></tr>
</table>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1 @@
{% extends "base.html" %}

View File

@ -0,0 +1,6 @@
{% extends "registration/registration_base.html" %}
{% block title %}Activation email sent{% endblock %}
{% block content %}
An activation email has been sent. Please check your email and click on the link to activate your account.
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends "registration/registration_base.html" %}
{% block title %}Register for an account{% endblock %}
{% block content %}
<div id="registration">
<table>
<form method='post' action=''>{% csrf_token %}
{{ form }}
<tr><td></td><td><input type="submit" value="Send activation email" /></td>
</form>
</table>
</div>
{% endblock %}

View File

@ -1,4 +1,8 @@
from django.template import RequestContext
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
def home(request): def home(request):
return render_to_response('home.html') return render_to_response('home.html',
{},
context_instance=RequestContext(request)
)

View File

@ -3,3 +3,5 @@ south
django-extensions django-extensions
django-tastypie django-tastypie
requests requests
hg+https://edsu@bitbucket.org/ubernostrum/django-registration

View File

@ -78,6 +78,7 @@ TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows. # Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths. # Don't forget to use absolute paths, not relative paths.
join(PROJECT_DIR, "frontend", "templates", "registration"),
) )
INSTALLED_APPS = ( INSTALLED_APPS = (
@ -92,6 +93,7 @@ INSTALLED_APPS = (
'regluit.frontend', 'regluit.frontend',
'regluit.api', 'regluit.api',
'regluit.core', 'regluit.core',
'registration',
) )
# A sample logging configuration. The only tangible logging # A sample logging configuration. The only tangible logging
@ -106,7 +108,12 @@ LOGGING = {
'mail_admins': { 'mail_admins': {
'level': 'ERROR', 'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler' 'class': 'django.utils.log.AdminEmailHandler'
} },
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': join(PROJECT_DIR, 'logs', 'django.log')
},
}, },
'loggers': { 'loggers': {
'django.request': { 'django.request': {
@ -116,3 +123,15 @@ LOGGING = {
}, },
} }
} }
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'ed.summers@gmail.com'
EMAIL_HOST_PASSWORD = 'naufxnpnlysskist'
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = 'ehs@pobox.com'
ACCOUNT_ACTIVATION_DAYS = 7
LOGIN_URL = "/accounts/login/"
LOGOUT_URL = "/accounts/logout/"

View File

@ -1,10 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
</body>
</html>

View File

@ -2,77 +2,77 @@
/* CSS Document */ /* CSS Document */
body{ body{
background:url(../images/bg-body.png) 0 0 repeat-x; background:url(../images/bg-body.png) 0 0 repeat-x;
padding:0 0 20px 0; padding:0 0 20px 0;
margin:0; margin:0;
font-size:12px; font-size:12px;
font-family: Lucida "Lucida Grande", "Lucida Sans Unicode", sans-serif, Helvetica, sans-serif; font-family: Lucida "Lucida Grande", "Lucida Sans Unicode", sans-serif, Helvetica, sans-serif;
color:#3d4e53; color:#3d4e53;
} }
.js-main{ .main{
width:960px; width:960px;
margin:0 auto; margin:0 auto;
clear:both; clear:both;
padding:0; padding:0;
} }
#js-header{ height:90px;} #header{ height:90px;}
.js-logo{ float:left; padding-top:20px;} .logo{ float:left; padding-top:20px;}
.js-topmenu{ float:right; padding-top:25px;} .topmenu{ float:right; padding-top:25px;}
.js-topmenu ul li{ float:left; padding:0 10px;} .topmenu ul li{ float:left; padding:0 10px;}
.js-topmenu ul li a{ height:36px; line-height:36px; display:block; color:#fff; text-decoration:none; font-weight:bold; font-size:13px; letter-spacing:1px; text-transform:capitalize;} .topmenu ul li a{ height:36px; line-height:36px; display:block; color:#fff; text-decoration:none; font-weight:bold; font-size:13px; letter-spacing:1px; text-transform:capitalize;}
.js-topmenu ul li.last a{ background: url(../images/bg.png) right top no-repeat;} .topmenu ul li.last a{ background: url(../images/bg.png) right top no-repeat;}
.js-topmenu ul li.last a span{ background:url(../images/bg.png) -770px -36px no-repeat; margin-right:29px; display:block; padding:0 5px 0 15px;} .topmenu ul li.last a span{ background:url(../images/bg.png) -770px -36px no-repeat; margin-right:29px; display:block; padding:0 5px 0 15px;}
#js-topsection{ padding:15px 0; overflow:hidden;} #topsection{ padding:15px 0; overflow:hidden;}
.js-topnews{ float:left; width:60%;} .topnews{ float:left; width:60%;}
.js-news-text{ float:left; width:70%; font-size:16px; color:#3d4e53; font-family:lucida grande;} .news-text{ float:left; width:70%; font-size:16px; color:#3d4e53; font-family:lucida grande;}
.js-news-links { float:right; width:30%;} .news-links { float:right; width:30%;}
.js-search{ float:right; width:30%;} .search{ float:right; width:30%;}
.js-search-inner{ float:right;} .search-inner{ float:right;}
.js-search .inputbox{ padding:0 0 0 15px; margin:0; border:none; background:url(../images/bg.png) -645px -180px; height:36px; line-height:36px; float: left; color:#6994a3;} .search .inputbox{ padding:0 0 0 15px; margin:0; border:none; background:url(../images/bg.png) -645px -180px; height:36px; line-height:36px; float: left; color:#6994a3;}
.js-search .button{ background:url(../images/bg.png) 100% -144px no-repeat; padding:0; margin:0; width:40px; height:36px; display:block; border:none; text-indent:-10000px; cursor:pointer;} .search .button{ background:url(../images/bg.png) 100% -144px no-repeat; padding:0; margin:0; width:40px; height:36px; display:block; border:none; text-indent:-10000px; cursor:pointer;}
#js-leftcol{ float:left; width:235px;} #leftcol{ float:left; width:235px;}
h3.jsmod-title{ background:url(../images/bg.png) 0 0 no-repeat; padding:0; margin:0; height:73px;} h3.jsmod-title{ background:url(../images/bg.png) 0 0 no-repeat; padding:0; margin:0; height:73px;}
h3.jsmod-title span{ background:url(../images/icon-h3.png) 90% center no-repeat; font-size:17px; color:#fff; h3.jsmod-title span{ background:url(../images/icon-h3.png) 90% center no-repeat; font-size:17px; color:#fff;
padding:26px 40px 27px 20px; padding:26px 40px 27px 20px;
display:block; display:block;
} }
#js-leftcol .jsmod-content{ border:1px solid #edf3f4; margin-left:10px; border-radius:0 0 10px 10px ;} #leftcol .jsmod-content{ border:1px solid #edf3f4; margin-left:10px; border-radius:0 0 10px 10px ;}
#js-leftcol ul.level1 > li > a{ text-transform:uppercase; color:#3d4e53; font-size:12px; border-bottom:1px solid #edf3f4;border-top:1px solid #edf3f4; display:block; padding:10px;} #leftcol ul.level1 > li > a{ text-transform:uppercase; color:#3d4e53; font-size:12px; border-bottom:1px solid #edf3f4;border-top:1px solid #edf3f4; display:block; padding:10px;}
#js-leftcol ul.level2 li{ #leftcol ul.level2 li{
padding:5px 10px; padding:5px 10px;
} }
#js-leftcol ul.level2 li a{ #leftcol ul.level2 li a{
color:#6994a3; color:#6994a3;
line-height: 20px; line-height: 20px;
} }
#js-leftcol a{ font-weight:normal;} #leftcol a{ font-weight:normal;}
#js-leftcol a:hover{ text-decoration:underline;} #leftcol a:hover{ text-decoration:underline;}
#js-maincol-fr{ float:right; width:725px;} #maincol-fr{ float:right; width:725px;}
div.content-block{ div.content-block{
overflow:hidden; overflow:hidden;
background:url(../images/bg.png) 100% -223px no-repeat; background:url(../images/bg.png) 100% -223px no-repeat;
padding:0 0 0 7px; padding:0 0 0 7px;
} }
h2.content-heading{ h2.content-heading{
padding:15px; margin:0; padding:15px; margin:0;
font-size:19px; font-size:19px;
font-weight:normal; font-weight:normal;
color:#3d4e53; color:#3d4e53;
float:left; width:70%; float:left; width:70%;
} }
h2.content-heading span{ font-style:italic;} h2.content-heading span{ font-style:italic;}
.content-block-heading a.block-link{ float:right; padding:15px; font-size:11px; color:#3d4e53; text-decoration:underline; font-weight:normal;} .content-block-heading a.block-link{ float:right; padding:15px; font-size:11px; color:#3d4e53; text-decoration:underline; font-weight:normal;}
@ -102,12 +102,32 @@ div.content-block-content .cols3 .column{ width:33.33%; float:left;}
.book-status span.percent21{ background:url(../images/images/icon-book6.png) 0 0 no-repeat;} .book-status span.percent21{ background:url(../images/images/icon-book6.png) 0 0 no-repeat;}
ul.menu{ ul.menu{
list-style:none; list-style:none;
padding:0; padding:0;
margin:0; margin:0;
line-height: 20px; line-height: 20px;
} }
a.readon{ background:url(../images/bg.png) 100% -72px no-repeat; color:#fff; text-transform:capitalize; display:block; float:right; font-size:13px; font-weight:bold;} a.readon{ background:url(../images/bg.png) 100% -72px no-repeat; color:#fff; text-transform:capitalize; display:block; float:right; font-size:13px; font-weight:bold;}
a.readon span{ background:url(../images/bg.png) -770px -108px no-repeat; margin-right:34px; padding:0 5px 0 20px; height:36px; line-height:36px; display:block;} a.readon span{ background:url(../images/bg.png) -770px -108px no-repeat; margin-right:34px; padding:0 5px 0 20px; height:36px; line-height:36px; display:block;}
a{ font-weight:bold; font-size:13px; text-decoration:none; cursor:pointer;} a{ font-weight:bold; font-size:13px; text-decoration:none; cursor:pointer;}
/* registration */
.errorlist {color: red}
#registration {
margin-left: auto;
margin-right: auto;
width: 30%;
margin-top: 5%;
}
#registration input[type="submit"] {
margin-left: auto;
margin-right: auto;
padding-left: 15px;
padding-right: 15px;
padding-top: 5px;
padding-bottom: 5px;
}

View File

@ -1,5 +1,6 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
urlpatterns = patterns('', urlpatterns = patterns('',
(r'^accounts/', include('registration.backends.default.urls')),
(r'', include('regluit.frontend.urls')), (r'', include('regluit.frontend.urls')),
) )