Skip to content

Commit

Permalink
Added a simple user profile edit form and view.
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobian committed Sep 27, 2011
1 parent dd7d2e7 commit 339f41d
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 12 deletions.
31 changes: 30 additions & 1 deletion django_website/accounts/forms.py
@@ -1,6 +1,35 @@
from __future__ import absolute_import
from django import forms
from registration.forms import RegistrationFormUniqueEmail
from .models import Profile

class RegistrationForm(RegistrationFormUniqueEmail):
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
del self.fields["tos"]
del self.fields["tos"]

class ProfileForm(forms.ModelForm):
"""
A form for editing user profiles.
Assumes that the Profile instance passed in has an associated User
object. The view (see views.py) takes care of tha
"""
class Meta(object):
model = Profile
fields = ['name']
email = forms.EmailField(required=False)

def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None)
if instance:
kwargs.setdefault('initial', {}).update({'email': instance.user.email})
super(ProfileForm, self).__init__(*args, **kwargs)

def save(self, commit=True):
instance = super(ProfileForm, self).save(commit=commit)
if 'email' in self.cleaned_data:
instance.user.email = self.cleaned_data['email']
if commit:
instance.user.save()
return instance
71 changes: 71 additions & 0 deletions django_website/accounts/migrations/0001_initial.py
@@ -0,0 +1,71 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

def forwards(self, orm):

# Adding model 'Profile'
db.create_table('accounts_profile', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
))
db.send_create_signal('accounts', ['Profile'])


def backwards(self, orm):

# Deleting model 'Profile'
db.delete_table('accounts_profile')


models = {
'accounts.profile': {
'Meta': {'object_name': 'Profile'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
},
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}

complete_apps = ['accounts']
Empty file.
9 changes: 9 additions & 0 deletions django_website/accounts/models.py
@@ -0,0 +1,9 @@
from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=200, blank=True)

def __unicode__(self):
return self.name or unicode(self.user)
5 changes: 5 additions & 0 deletions django_website/accounts/urls.py
Expand Up @@ -11,6 +11,11 @@
{'form_class': RegistrationFormUniqueEmail},
name='registration_register',
),
url(
r'^edit/$',
account_views.edit_profile,
name='edit_profile',
),
url(
r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
'django.contrib.auth.views.password_reset_confirm',
Expand Down
16 changes: 14 additions & 2 deletions django_website/accounts/views.py
Expand Up @@ -2,25 +2,37 @@

import hashlib
import json
from django.shortcuts import render, get_object_or_404
from django.shortcuts import redirect, render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.conf import settings
from django.core import cache
from django.http import HttpResponse
from .forms import ProfileForm
from .models import Profile
from ..trac import stats as trac_stats
from ..cla.models import find_agreements

def user_profile(request, username):
u = get_object_or_404(User, username=username)
ctx = {
'profile': u,
'user_obj': u,
'email_hash': hashlib.md5(u.email).hexdigest(),
'user_can_commit': u.has_perm('auth.commit'),
'clas': find_agreements(u),
'stats': get_user_stats(u),
}
return render(request, "accounts/user_profile.html", ctx)

@login_required
def edit_profile(request):
profile, created = Profile.objects.get_or_create(user=request.user)
form = ProfileForm(request.POST or None, instance=profile)
if form.is_valid():
form.save()
return redirect('user_profile', request.user.username)
return render(request, "accounts/edit_profile.html", {'form': form})

def json_user_info(request):
"""
Return info about some users as a JSON object.
Expand Down
1 change: 1 addition & 0 deletions django_website/settings/www.py
Expand Up @@ -69,6 +69,7 @@
'django.contrib.sitemaps',
'django_push.subscriber',
'django_website.blog',
'django_website.accounts',
'django_website.aggregator',
'django_website.cla',
'django_website.docs',
Expand Down
44 changes: 44 additions & 0 deletions django_website/templates/accounts/edit_profile.html
@@ -0,0 +1,44 @@
{% extends "registration/base.html" %}

{% block title %}Edit your profile{% endblock %}

{% block content %}

{% if form.errors %}
<p class="errors">Please correct the errors below: {{ form.non_field_errors }}</p>
{% endif %}

<h1>Edit your profile</h1>

<form method="post" action="" class="wide">
{% csrf_token %}
<p>
<label for="id_name">Your name:</label>
{% if form.name.errors %}
<p class="errors">{{ form.name.errors.as_text }}</p>
{% endif %}
{{ form.name }}
</p>
<p>
<label for="id_email">Your email address:</label>
{% if form.email.errors %}
<p class="errors">{{ form.email.errors.as_text }}</p>
{% endif %}
{{ form.email }}
</p>
<p class="submit"><input type="submit" value="Save &rarr;"></p>
{% endblock %}

{% block content-related %}
<h2>Help</h2>
<p>Use this form to edit your profile.</p>

<p>Use whatever name you'd like to be identified with on djangoproject.com. If
you leave it blank, we'll identify you as <b>{{ user.username }}</b>, your
username.</p>

<p>We hate spam as much as you do. We'll only use it to send you password reset
emails. We'll also use this email to try to fetch a <a
href="http://en.gravatar.com/">Gravatar</a>. You can change the image for this
email at <a href="http://en.gravatar.com/">Gravatar</a>.</p>
{% endblock %}
20 changes: 11 additions & 9 deletions django_website/templates/accounts/user_profile.html
@@ -1,27 +1,29 @@
{% extends "base_community.html" %}

{% block title %}{% firstof profile.get_full_name profile.username %}{% endblock %}
{% block title %}{% firstof user_obj.profile.name user_obj.username %}{% endblock %}
{% block extrahead %}
<style type="text/css">
#avatar { float: left; margin-top: 16px; }
#user-info { padding-left: 160px; }
#user-info ul li { margin-left: 1em; }
h1 span.badge {
h1 span.badge {
font-size: 12px;
background-color: #FFC757;
border-radius: 4px;
padding: 2px 6px;
padding: 2px 6px;
position: relative;
bottom: 0.3em;
}
</style>
{% endblock extrahead %}
{% block content-related %}
<h2>Is this you?</h3>
{% load url from future %}
<h2>{% if user_obj == user %}This is you!{% else %}Is this you?{% endif %}</h2>
<p>
Need to edit something? Here's how:
</p>
<ul>
<li><a href="{% url "edit_profile" %}">Edit your name and email here.</a></li>
<li>
The image is the <a href="http://en.gravatar.com/">Gravatar</a> linked
to the email address you signed up with. You can change the image over
Expand All @@ -42,26 +44,26 @@ <h2>Is this you?</h3>
src="http://robohash.org/{{ email_hash }}?gravatar=hashed&amp;set=set3">
<div id="user-info">
<h1>
{% firstof profile.get_full_name profile.username %}
{% firstof user_obj.profile.name user_obj.username %}
{% if user_can_commit %}<span class="badge" title="Core committer.">core</span>{% endif %}
{% if clas %}<span class="badge" title="Contributor License Agreement on file.">cla</span>{% endif %}
</h1>

{% if stats %}
<h2>Lies, damned lies, and statistics:</h2>
<ul>
{% for stat, value in stats.items %}
<li>{{ stat }}: {{ value|intcomma }}.</li>
<li>{{ stat }}: {{ value|intcomma }}.</li>
{% endfor %}
</ul>
{% endif %}

{% with proflie.owned_feeds.all as feeds %}
{% with user_obj.owned_feeds.all as feeds %}
{% if feeds %}
<h2>Community feeds:</h2>
<ul>
{% for f in feeds %}
<li><a href="{{ f.public_url }}">{{ f.title }}</a></li>
<li><a href="{{ f.public_url }}">{{ f.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
Expand Down

0 comments on commit 339f41d

Please sign in to comment.