Commits

Michael Godshall committed 97abb9a

Integration of django-registration and django-profiles

  • Participants
  • Parent commits e309b66

Comments (0)

Files changed (31)

     cp rustynail/local_settings.txt rustynail/local_settings.py
     python manage.py syncdb
 	python manage.py runserver
-	
-
-Loading Test Data
-=================
-
-Populate the site with test data by loading fixtures::
-
-	python manage.py loaddata test_data.json
 django-debug-toolbar
 #django-test-utils==0.3
 
+-e hg+http://bitbucket.org/ubernostrum/django-registration/#egg=django-registration
+django-profiles
+#django-avatar
+
 # PYTHON PACKAGES
 PIL
 #docutils

rustynail/apps/accounts/__init__.py

Empty file added.

rustynail/apps/accounts/forms.py

+from django import forms
+from django.contrib.auth.models import User
+
+from accounts.models import UserProfile
+
+    
+class UserProfileForm(forms.ModelForm):
+    """
+    Form to update a user's profile
+    """
+    def __init__(self, *args, **kwargs):
+        super(UserProfileForm, self).__init__(*args, **kwargs)
+        try:
+            self.fields['first_name'].initial = self.instance.user.first_name
+            self.fields['last_name'].initial = self.instance.user.last_name
+            self.fields['email'].initial = self.instance.user.email
+        except User.DoesNotExist:
+            pass
+
+    first_name = forms.CharField(max_length=50,
+                                widget=forms.TextInput(),
+                                label="First name")
+    last_name = forms.CharField(max_length=50,
+                                widget=forms.TextInput(),
+                                label="Last name")
+    email = forms.EmailField(widget=forms.TextInput(attrs=dict(maxlength=75)),
+                             label="Email address")
+
+    class Meta:
+      model = UserProfile
+      exclude = ('user',)
+
+    def clean_email(self):
+        """
+        Validate that the supplied email address is unique for the site.
+        """
+        if User.objects.exclude(username__iexact=self.instance.user.username).filter(email__iexact=self.cleaned_data['email']):
+            raise forms.ValidationError("A user is already registered with this email address.  Please choose a different one.")
+        return self.cleaned_data['email']
+
+    def save(self, *args, **kwargs):
+        """
+        Update the primary email address on the related User object as well.
+        """
+        u = self.instance.user
+        u.email = self.cleaned_data['email']
+        u.first_name = self.cleaned_data['first_name']
+        u.last_name = self.cleaned_data['last_name']
+        u.save()
+        profile = super(UserProfileForm, self).save(*args,**kwargs)
+        return profile

rustynail/apps/accounts/models.py

+from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
+from django.db import models
+from django.db.models import signals
+
+
+class UserProfile(models.Model):
+    """
+    User Profile model for storing extra account info and preferences.
+
+    See 
+    """
+    user = models.OneToOneField(User)
+
+    class Meta:
+        verbose_name = "user profile"
+        verbose_name_plural = "user profiles"
+
+    def __unicode__(self):
+        return self.user.username
+
+    def get_absolute_url(self):
+        return reverse("profiles_profile_detail", kwargs={"username": self.user.username})
+
+def create_profile(sender, instance, signal, created, **kwargs):
+    """
+    When a user creates an account, also create a profile for that user
+    """
+    if created:
+        profile, created = UserProfile.objects.get_or_create(user=instance)
+signals.post_save.connect(create_profile, sender=User)

rustynail/apps/accounts/tests.py

+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)

rustynail/apps/accounts/views.py

+# Create your views here.

rustynail/settings.py

     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
-    'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
-	'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
+    #'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
+	#'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
 )
 
 ROOT_URLCONF = 'rustynail.urls'
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'django.contrib.admin',
-    # 'django.contrib.admindocs',
-	#'django.contrib.flatpages',
-	#'django.contrib.humanize',
-	#'django.contrib.redirects',
 	'south',
 	'django_extensions',
+
+    'registration',
+    'profiles',
+    'accounts',
+    
 )
 
 MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
     }
 }
 
+#Django Registration Settings
+ACCOUNT_ACTIVATION_DAYS = 7 #This is the number of days users will have to activate their accounts after registering.
+REGISTRATION_OPEN = True
+
+AUTH_PROFILE_MODULE = 'accounts.UserProfile'
+LOGIN_REDIRECT_URL = '/profiles/'
+
+ABSOLUTE_URL_OVERRIDES = {
+    'auth.user': lambda u: '/profiles/%s/' % u.username,
+}
+
+#ACCOUNT_EMAIL_REQUIRED = False
+#ACCOUNT_EMAIL_VERIFICATION = False
+#ACCOUNT_EMAIL_AUTHENTICATION = False
+#ACCOUNT_UNIQUE_EMAIL = True
+#SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED
+#SOCIALACCOUNT_AUTO_SIGNUP = True
+#SOCIALACCOUNT_AVATAR_SUPPORT = 'avatar'
+#EMAIL_CONFIRMATION_DAYS = 5 # number of days before confirmation emails will expire
 
 try:
     from local_settings import *

rustynail/static/css/main.css

Empty file added.

rustynail/templates/admin/base_site.html

 {% extends "admin/base.html" %}
 {% load i18n %}
 
-{% block title %}{{ title }} | {% trans "rustynail Admin" %}{% endblock %}
+{% block title %}{{ title }} | {% trans "Rusty Nail Admin" %}{% endblock %}
 
 {% block branding %}
-<h1 id="site-name">{% trans "rustynail Admin" %}</h1>
+<h1 id="site-name">{% trans "Rusty Nail Admin" %}</h1>
 {% endblock %}
 
 {% block nav-global %}{% endblock %}

rustynail/templates/base.html

 <html>
 <head>
 	<meta charset="utf-8">
-    <title>{% block head_title %}{% endblock %}</title>
+    <title>{% block title_base %}{% block title %}{% endblock %} - Rusty Nail{% endblock %}</title>
+    <link rel="stylesheet" type="text/css" charset="utf-8" href="{{ STATIC_URL }}css/main.css" media="screen" />
+    {% block extra_head %}{% endblock %}
 </head>
 <body>
+    <div id="main_menu">
+
+        {% block menu_base %}{% block menu %}{% endblock %}{% endblock %}
+
+        {% block login %}
+        <ul>
+            <li><a href="{% url home %}">Home</a></li>
+            <li><a href="{% url profiles_profile_list %}">Profiles</a></li>
+            {% if user.is_authenticated %}
+                <li><b><a href="{% url profiles_profile_detail user %}">{{ user }}</a></b> | <a href="{% url auth_logout %}">Logout</a></li>
+            {% else %}
+                <li><a href="{% url registration_register %}">Sign Up</a></li>
+                <li><a href="{% url auth_login %}">Login</a></li>
+            {% endif %}
+        </ul>
+        {% endblock %}
+
+    </div>
+    
 	{% block content %}{% endblock %}
 </body>
 </html>

rustynail/templates/home.html

+{% extends "base.html" %}
+{% block title %}Welcome{% endblock %}
+
+{% block content %}
+<h1>Welcome to Rusty Nail</h1>
+{% endblock content %}

rustynail/templates/profiles/create_profile.html

+{% extends "base.html" %}
+{% block title %}Create Profile{% endblock %}
+
+{% block content %}
+<h1>Create your profile</h1>
+
+<form method="POST" action="">{% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" name="submit" value="Update" id="submit">
+</form>
+{% endblock content %}

rustynail/templates/profiles/edit_profile.html

+{% extends "base.html" %}
+{% block title %}Edit Profile{% endblock %}
+
+{% block content %}
+<h1>Edit your profile</h1>
+
+<form method="POST" action="">{% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" name="submit" value="Update" id="submit">
+</form>
+{% endblock content %}

rustynail/templates/profiles/profile_detail.html

+{% extends "base.html" %}
+{% block title %}Profile for {{ profile.user.username }}{% endblock %}
+
+{% block content %}
+<h1>Profile for {{ profile.user.username }}</h1>
+
+{% if user.is_authenticated %}
+    {% if user == profile.user %}
+        <a href="{% url profiles_edit_profile %}">Edit Profile</a>
+    {% endif %}
+{% endif %}
+
+<ul>
+    <li>Name: {{ profile.user.get_full_name }}</li>
+    <li>Email: {{ profile.user.email }}</li>
+</ul>
+{% endblock content %}

rustynail/templates/profiles/profile_list.html

+{% extends "base.html" %}
+{% block title %}Profile List{% endblock %}
+
+{% block content %}
+<h1>Profile List</h1>
+
+<ul>
+{% for profile in object_list %}
+    <li><a href="{{ profile.get_absolute_url }}">{{ profile.user.username }}</a></li>
+{% endfor %}
+</ul>
+{% endblock content %}

rustynail/templates/registration/activate.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+{% comment %}
+**registration/activate.html**
+
+Used if account activation fails. With the default setup, has the following context:
+
+``account``
+    Whether or not the activation has been succesfull and perhaps also some
+    information about the actual account.
+{% endcomment %}
+
+{% block registration %}
+{% if account %}
+    <h1>{% trans "Activation successful" %}</h1>
+    {% url auth_login as login_url %}
+    <p>{% blocktrans %}You can now proceed to <a href="{{ login_url }}">login.</a>{% endblocktrans %}</p>
+{% else %}
+    <h1>{% trans "Activation failed" %}</h1>
+    <p>{% trans "Something went wrong while activating your account. This might mean that the activation code was wrong or that your account has already been activated." %}</p>
+{% endif %}
+{% endblock %}

rustynail/templates/registration/activation_email.txt

+{% comment %}
+**registration/activation_email.txt**
+
+Used to generate the body of the activation email. Should display a
+link the user can click to activate the account. This template has the
+following context:
+
+``activation_key``
+    The activation key for the new account.
+
+``expiration_days``
+    The number of days remaining during which the account may be
+    activated.
+
+``site``
+    An object representing the site on which the user registered;
+    depending on whether ``django.contrib.sites`` is installed, this
+    may be an instance of either ``django.contrib.sites.models.Site``
+    (if the sites application is installed) or
+    ``django.contrib.sites.models.RequestSite`` (if not). Consult `the
+    documentation for the Django sites framework
+    <http://docs.djangoproject.com/en/dev/ref/contrib/sites/>`_ for
+    details regarding these objects' interfaces.
+{% endcomment %}{% load i18n %}
+{% url registration_activate_url activation_key as activate_url %}
+{% blocktrans with site.name as site_name and site.domain as site_domain %}
+Dear,
+
+You have created an account for {{ site_name }}, which has to
+be activated. To do this, please follow the following link:
+http://{{ site_domain }}{{ activate_url }}
+
+Please do take note that if your activation does not succeed
+within {{ expiration_days }} days, you will have to restart
+the activation process.
+
+Kind regards,
+The Webmaster
+{% endblocktrans %}

rustynail/templates/registration/activation_email_subject.txt

+{% comment %}
+**registration/activation_email_subject.txt**
+
+Used to generate the subject line of the activation email. Because the
+subject line of an email must be a single line of text, any output
+from this template will be forcibly condensed to a single line before
+being used. This template has the following context:
+
+``activation_key``
+    The activation key for the new account.
+
+``expiration_days``
+    The number of days remaining during which the account may be
+    activated.
+
+``site``
+    An object representing the site on which the user registered;
+    depending on whether ``django.contrib.sites`` is installed, this
+    may be an instance of either ``django.contrib.sites.models.Site``
+    (if the sites application is installed) or
+    ``django.contrib.sites.models.RequestSite`` (if not). Consult `the
+    documentation for the Django sites framework
+    <http://docs.djangoproject.com/en/dev/ref/contrib/sites/>`_ for
+    details regarding these objects' interfaces.
+{% endcomment %}{% load i18n %}
+{% blocktrans with site.name as site_name %}Account activation for {{ site_name }}{% endblocktrans %}

rustynail/templates/registration/base.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{{ LANGUAGE_CODE }}" lang="{{ LANGUAGE_CODE }}">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+	<title>{% block registration_title %}{% endblock %}</title>
+	{% block htmlheader %}{% endblock %}
+</head>
+
+<body>
+    {% block registration %}{% endblock %}
+</body>
+</html>

rustynail/templates/registration/login.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+{% comment %}
+**registration/login.html**
+
+It's your responsibility to provide the login form in a template called
+registration/login.html by default. This template gets passed four
+template context variables:
+
+``form``
+    A Form object representing the login form. See the forms
+    documentation for more on Form objects.
+
+``next``
+    The URL to redirect to after successful login. This may contain a
+    query string, too.
+
+``site``
+    The current Site, according to the SITE_ID setting. If you don't
+    have the site framework installed, this will be set to an instance
+    of RequestSite, which derives the site name and domain from the
+    current HttpRequest.
+
+``site_name``
+    An alias for site.name. If you don't have the site framework
+    installed, this will be set to the value of
+    request.META['SERVER_NAME']. For more on sites, see The
+    "sites" framework.
+{% endcomment %}
+
+{% block registration %}
+<h1>{% trans "Login" %}</h1>
+
+<form action="" method="post">{% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" value="{% trans "Login" %}">
+</form>
+        
+<p><a href="{% url registration_register %}">{% trans "Create an account" %}</a></p>
+<p><a href="{% url auth_password_reset %}">{% trans "Reset your password" %}</a></p>
+{% endblock %}

rustynail/templates/registration/logout.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+<h1>Logout</h1>
+<a href="{% url auth_login %}">Login again</a>
+{% endblock %}

rustynail/templates/registration/password_change_done.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+<h1>{% trans 'Password change successful' %}</h1>
+
+<p>{% trans 'Your password was changed.' %}</p>
+{% endblock %}
+d

rustynail/templates/registration/password_change_form.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+<h1>{% trans 'Password change' %}</h1>
+
+<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
+
+<form action="" method="post">{% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" name="some_name" value="{% trans 'Change my password' %}">
+</form>
+{% endblock %}

rustynail/templates/registration/password_reset_complete.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+<h1>{% trans 'Password reset complete' %}</h1>
+
+<p>{% trans "Your password has been set.  You may go ahead and log in now." %}</p>
+
+<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
+{% endblock %}

rustynail/templates/registration/password_reset_confirm.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+{% if validlink %}
+
+<h1>{% trans 'Enter new password' %}</h1>
+
+<p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
+
+<form action="" method="post">
+{% csrf_token %}
+{{ form }}
+<input type="submit" value="{% trans 'Change my password' %}" />
+</form>
+
+{% else %}
+
+<h1>{% trans 'Password reset unsuccessful' %}</h1>
+
+<p>{% trans "The password reset link was invalid, possibly because it has already been used.  Please request a new password reset." %}</p>
+
+{% endif %}
+{% endblock %}

rustynail/templates/registration/password_reset_done.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+<h1>{% trans 'Password reset successful' %}</h1>
+
+<p>{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}</p>
+{% endblock %}

rustynail/templates/registration/password_reset_form.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+
+{% block registration %}
+<h1>{% trans "Password reset" %}</h1>
+<p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>
+<form action="" method="post">{% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" value="{% trans 'Reset my password' %}">
+</form>
+{% endblock %}

rustynail/templates/registration/registration_complete.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+{% comment %}
+**registration/registration_complete.html**
+
+Used after successful completion of the registration form. This
+template has no context variables of its own, and should simply inform
+the user that an email containing account-activation information has
+been sent.
+{% endcomment %}
+
+{% block registration %}
+<h1>{% trans "User registration successful" %}</h1>
+<p>{% trans "We've e-mailed you instructions for activating your account to the e-mail address you submitted. You should be receiving it shortly." %}</p>
+{% endblock %}

rustynail/templates/registration/registration_form.html

+{% extends "registration/base.html" %}
+{% load i18n %}
+{% comment %}
+**registration/registration_form.html**
+Used to show the form users will fill out to register. By default, has
+the following context:
+
+``form``
+    The registration form. This will be an instance of some subclass
+    of ``django.forms.Form``; consult `Django's forms documentation
+    <http://docs.djangoproject.com/en/dev/topics/forms/>`_ for
+    information on how to display this in a template.
+{% endcomment %}
+
+{% block registration %}
+<h1>{% trans "User registration" %}</h1>
+<form action="" method="post">{% csrf_token %}
+    {{ form.as_p }}
+    <input type="submit" name="some_name" value="{% trans "Create account" %}">
+</form>
+{% endblock %}

rustynail/urls.py

 from django.conf.urls.defaults import *
-
 from django.contrib import admin
+from django.views.generic.base import TemplateView
 admin.autodiscover()
 
+from accounts.forms import UserProfileForm
+from registration.forms import RegistrationFormUniqueEmail
+from registration.views import register
+
 urlpatterns = patterns('',
-   # Example:
-   # (r'^django13/', include('django13.foo.urls')),
-
-   # Uncomment the admin/doc line below to enable admin documentation:
-   # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
-
-   (r'^admin/', include(admin.site.urls)),
+    url(r'^$', TemplateView.as_view(template_name="home.html"), name="home"),
+    (r'^accounts/register/', register, {'backend': 'registration.backends.simple.SimpleBackend',
+                                        'form_class': RegistrationFormUniqueEmail,}),
+    (r'^accounts/', include('registration.backends.simple.urls')),
+    (r'^profiles/edit/', 'profiles.views.edit_profile', {'form_class': UserProfileForm,}),
+    (r'^profiles/', include('profiles.urls')),
+    (r'^admin/', include(admin.site.urls)),
 )