Permalink
Browse files

Added a simple user profile edit form and view.

  • Loading branch information...
1 parent dd7d2e7 commit 339f41dafe4be4dd6728903d4d281523b541a099 @jacobian jacobian committed Sep 27, 2011
@@ -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
@@ -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']
@@ -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)
@@ -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',
@@ -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.
@@ -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',
@@ -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 %}
@@ -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
@@ -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 %}

0 comments on commit 339f41d

Please sign in to comment.