Vereinfachung Membership ist nun ein custom login model, keine Abhängikeiten mehr zu auth.User.

absofort können alle Benutzer ins Ranking eingetragen werden und nicht mehr nur "zahlende Mitglieder".
This commit is contained in:
Christian Berg
2015-08-10 20:49:07 +02:00
committed by Christian Berg
parent b96b485b61
commit bafbf38612
100 changed files with 3857 additions and 420 deletions

View File

@@ -35,7 +35,7 @@ class MembershipAdmin(admin.ModelAdmin):
list_filter = ('membership', 'confirmed')
list_display = (
'admin_thumbnail',
'nickname',
'username',
'first_name',
'last_name',
'membership',
@@ -43,20 +43,19 @@ class MembershipAdmin(admin.ModelAdmin):
'paid_until',
)
list_editable = ('confirmed', 'paid_until',)
list_display_links = ('nickname',)
list_display_links = ('username',)
fieldsets = (
(None, {
'fields': (
'gender', ('first_name', 'last_name'), ('email', 'website'))
}),
(_('Membership'), {
'classes': ('collapse',),
'fields': (('membership', 'confirmed'), 'birthday', 'telephone',
'street_name', ('post_code', 'city'))
}),
(None, {'fields': (('username', 'password'), 'gender',
('first_name', 'last_name'), ('email', 'website'))}),
(_('Membership'), {'classes': ('collapse',),
'fields': (('membership', 'confirmed'), 'birthday', 'telephone',
'street_name', ('post_code', 'city'))}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
ordering = ('nickname',)
search_fields = ('nickname', 'first_name', 'last_name',)
ordering = ('username',)
search_fields = ('username', 'first_name', 'last_name',)
admin.site.register(Membership, MembershipAdmin)

View File

@@ -21,7 +21,7 @@ class MembershipForm(forms.ModelForm):
class Meta:
model = models.Membership
fields = (
'nickname', 'gender', 'first_name', 'last_name', 'email', 'avatar',
'username', 'gender', 'first_name', 'last_name', 'email', 'avatar',
'website', 'membership', 'birthday', 'telephone', 'street_name',
'post_code', 'city', 'comment'
)

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.core.validators
import django.contrib.auth.models
from django.conf import settings
import django.utils.timezone
import membership.models
import utils
class Migration(migrations.Migration):
dependencies = [
('auth', '0006_require_contenttypes_0002'),
]
operations = [
migrations.CreateModel(
name='Membership',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, max_length=30, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, verbose_name='username')),
('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)),
('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)),
('email', models.EmailField(max_length=254, verbose_name='email address', blank=True)),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('gender', models.CharField(max_length=1, verbose_name='Geschlecht', choices=[(b'm', 'M\xe4nnlich'), (b'f', 'Weiblich')])),
('website', models.URLField(blank=True)),
('avatar', models.ImageField(storage=utils.OverwriteStorage(), null=True, upload_to=membership.models.get_upload_path, blank=True)),
('membership', models.BooleanField(default=False, help_text='Ja, ich bin mit den Statuen einverstanden und m\xf6chte Mitglied werden.', verbose_name='Mitgliedschaft')),
('birthday', models.DateField(null=True, verbose_name='Geburtstag', blank=True)),
('telephone', models.CharField(max_length=30, null=True, verbose_name='Telefon', blank=True)),
('street_name', models.CharField(max_length=75, null=True, verbose_name='Adresse', blank=True)),
('post_code', models.PositiveSmallIntegerField(null=True, verbose_name='Postleitzahl', blank=True)),
('city', models.CharField(max_length=75, null=True, verbose_name='Ort', blank=True)),
('deposit', models.PositiveSmallIntegerField(default=0, editable=False)),
('registration_date', models.DateField(auto_now_add=True)),
('paid_until', models.DateField(null=True, verbose_name='Bezahlt bis', blank=True)),
('confirmed', models.BooleanField(default=False, help_text='Diese Person hat ihre Mitgliedschaft bezahlt', verbose_name='Best\xe4tigt')),
('comment', models.TextField(blank=True)),
('groups', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', verbose_name='groups')),
('user_permissions', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Permission', blank=True, help_text='Specific permissions for this user.', verbose_name='user permissions')),
],
options={
'ordering': ('last_name', 'first_name'),
'swappable': 'AUTH_USER_MODEL',
'verbose_name': 'Mitgliedschaft',
'verbose_name_plural': 'Mitgliedschaften',
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='ActivationRequest',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('activation_key', models.CharField(max_length=40, verbose_name='Aktivierungsschl\xfcssel')),
('user', models.OneToOneField(verbose_name='Benutzer', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Ausstehende Aktivierung',
'verbose_name_plural': 'Wartende Aktivierungen',
},
),
]

View File

View File

@@ -7,7 +7,8 @@ import hashlib
from django.utils import timezone
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib import auth
from django.contrib.auth.models import AbstractUser
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.translation import ugettext as _
@@ -32,7 +33,7 @@ def get_upload_path(instance, filename):
@param filename: the filename of the uploaded image
"""
extension = path.splitext(filename)[1]
return 'membership/%s%s' % (instance.user.username, extension)
return 'membership/%s%s' % (instance.username, extension)
class ActivationManager(models.Manager):
@@ -139,7 +140,7 @@ class ActivationRequest(models.Model):
def username(self):
return self.user.username
'''
class MembershipManager(models.Manager):
def get(self, user=None, username=None, **kwargs):
"""
@@ -150,7 +151,7 @@ class MembershipManager(models.Manager):
"""
try:
if username and not user:
user = get_user_model().objects.get(username=username)
user = auth.get_user_model().objects.get(username=username)
return super(MembershipManager, self).get(user=user)
except Membership.DoesNotExist:
membership = Membership(
@@ -162,19 +163,19 @@ class MembershipManager(models.Manager):
)
membership.save()
return membership
'''
class Membership(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
nickname = models.SlugField(_('Nickname'), unique=True)
class Membership(AbstractUser):
# user = models.OneToOneField(settings.AUTH_USER_MODEL)
# nickname = models.SlugField(_('Nickname'), unique=True)
gender = models.CharField(
_("Gender"),
max_length=1,
choices=GENDER_CHOICES
)
first_name = models.CharField(_("Given Name"), max_length=30)
last_name = models.CharField(_("Last Name"), max_length=30)
email = models.EmailField(_('Email'), unique=True)
# first_name = models.CharField(_("Given Name"), max_length=30)
# last_name = models.CharField(_("Last Name"), max_length=30)
# email = models.EmailField(_('Email'), unique=True)
website = models.URLField(blank=True)
avatar = models.ImageField(
upload_to=get_upload_path,
@@ -226,7 +227,7 @@ class Membership(models.Model):
help_text=_('This person has paid the membership fee.')
)
comment = models.TextField(blank=True)
objects = MembershipManager()
# objects = MembershipManager()
thumbnail = ImageSpecField(
processors=[SmartResize(width=60, height=60)],
@@ -242,15 +243,17 @@ class Membership(models.Model):
class Meta(object):
ordering = ('last_name', 'first_name',)
swappable = 'AUTH_USER_MODEL'
verbose_name = _('Membership')
verbose_name_plural = _('Memberships')
def __unicode__(self):
return _('Userprofile for %s' % self.user.username)
return self.username
def clean(self):
# Update the Profile Info from the User Object
'''
if not self.nickname:
self.nickname = self.user.username
if not self.first_name:
@@ -259,23 +262,24 @@ class Membership(models.Model):
self.last_name = self.user.last_name
if not self.email:
self.email = self.user.email
'''
def get_absolute_url(self):
return reverse(
'membership-details',
kwargs={'username': self.user.username}
kwargs={'username': self.username}
)
def save(self, *args, **kwargs):
super(Membership, self).save(*args, **kwargs)
'''
self.user.username = self.nickname
self.user.first_name = self.first_name
self.user.last_name = self.last_name
self.user.email = self.email
'''
if self.confirmed:
self.user.groups.add(PAID_MEMBERSHIP_GROUP)
self.groups.add(PAID_MEMBERSHIP_GROUP)
else:
self.user.groups.remove(PAID_MEMBERSHIP_GROUP)
self.user.save()
self.groups.remove(PAID_MEMBERSHIP_GROUP)

View File

@@ -3,15 +3,15 @@
{% block title %}{{ membership.first_name }} {{membership.last_name}}{% endblock %}
{% block teaser %}<h1>{% trans 'profile for' %} {{membership.user.username|title}}</h1>{% endblock %}
{% block teaser %}<h1>{% trans 'profile for' %} {{membership.username|title}}</h1>{% endblock %}
{% block navigation %}
<ul id="navigation">
<li><a href="{% url 'player-ladder-score' membership.user.username %}">{% trans "Ladder Hanchans" %}</a></li>
<li><a href="{% url 'player-kyu-score' membership.user.username %}">{% trans "Kyu Hanchans" %}</a></li>
<li><a href="{% url 'player-dan-score' membership.user.username %}">{% trans "Dan Hanchans" %}</a></li>
<li><a href="{% url 'player-invalid-score' membership.user.username %}">{% trans "Invalid Hanchans" %}</a></li>
<li><a href="{% url 'maistar-player-games' membership.user.username %}">{% trans "Mai-Star Games" %}</a></li>
<li><a href="{% url 'player-ladder-score' membership.username %}">{% trans "Ladder Hanchans" %}</a></li>
<li><a href="{% url 'player-kyu-score' membership.username %}">{% trans "Kyu Hanchans" %}</a></li>
<li><a href="{% url 'player-dan-score' membership.username %}">{% trans "Dan Hanchans" %}</a></li>
<li><a href="{% url 'player-invalid-score' membership.username %}">{% trans "Invalid Hanchans" %}</a></li>
<li><a href="{% url 'maistar-player-games' membership.username %}">{% trans "Mai-Star Games" %}</a></li>
</ul>
{% endblock %}
@@ -25,8 +25,8 @@
<div class="grid_6">
<ul>
<li><strong>Name:</strong> {{membership.first_name}} {{membership.last_name}}</li>
<li><strong>{% trans "Member Since" %}:</strong> {{membership.user.date_joined}}</li>
<li><strong>{% trans "Last Login" %}:</strong> {{membership.user.last_login}}</li>
<li><strong>{% trans "Member Since" %}:</strong> {{membership.date_joined}}</li>
<li><strong>{% trans "Last Login" %}:</strong> {{membership.last_login}}</li>
{% if website %}
<li><strong>Homepage:</strong> <a href="{{website}}">{{website}}</a></li>
{% endif %}
@@ -48,26 +48,26 @@
{% endif %}
</div>
{% ifequal membership.user user %}
{% ifequal membership user %}
<div class="grid_3">
<a href="{% url 'membership-edit' membership.user.username %}" class="button">
<img src="{{STATIC_URL}}icons/user_edit.png" alt="{% trans 'Edit Userprofile' %}" width="16" height="16"/>
<a href="{% url 'membership-edit' membership.username %}" class="button">
<span class="fa fa-pencil"></span>
{% trans "Edit Profile" %}
</a>
<a href="{% url 'password_change' %}" class="button">
<img src="{{STATIC_URL}}icons/lock_edit.png" alt="{% trans 'Change Password' %}" width="16" height="16"/>
<span class="fa fa-key"></span>
{% trans 'Change Password' %}
</a>
<a class="button" href="{% url 'social:begin' 'facebook' %}" rel="nofollow">
<img src="{{STATIC_URL}}img/facebook.png" alt="{% trans 'Associate' %}" width="26" height="26"/>
<span class="fa fa-facebook"></span>
{% blocktrans with 'Facebook' as name %}Associate with {{ name }}{% endblocktrans %}
</a>
<a class="button" href="{% url 'social:begin' 'twitter' %}" rel="nofollow">
<img src="{{STATIC_URL}}img/twitter.png" alt="{% trans 'Associate' %}" width="26" height="26"/>
<span class="fa fa-twitter"></span>
{% blocktrans with 'Twitter' as name %}Associate with {{ name }}{% endblocktrans %}
</a>
<a class="button" href="{% url 'social:begin' 'google-oauth2' %}" rel="nofollow">
<img src="{{STATIC_URL}}img/google.png" alt="{% trans 'Associate' %}" width="26" height="26"/>
<span class="fa fa-google-plus"></span>
{% blocktrans with 'Google' as name %}Associate with {{ name }}{% endblocktrans %}
</a>

View File

@@ -17,14 +17,8 @@
{% csrf_token %}
{% include 'form.html' %}
<p class="buttonbar">
<button type="reset">
<img src="{{STATIC_URL}}icons/arrow_undo.png" alt="{% trans 'reset' %}" />
{% trans "Reset" %}
</button>
<button type="submit">
<img src="{{STATIC_URL}}icons/disk.png" alt="{% trans 'save' %}" />
{% trans "Save" %}
</button>
<button type="reset"><span class="fa fa-undo"></span> {% trans "Reset" %}</button>
<button type="submit"><span class="fa fa-hdd-o"></span> {% trans "Save" %}</button>
</p>
</fieldset>
</form>

View File

@@ -27,13 +27,10 @@
confirm your email address, otherwise your can't login.
{% endblocktrans %}</p>
<p class="buttonbar">
<button type="reset"><img src="{{STATIC_URL}}icons/arrow_undo.png" alt="{% trans 'reset' %}" /> {% trans 'reset' %}</button>
<button type="submit"><img src="{{STATIC_URL}}icons/user_add.png" alt="{% trans 'register' %}" /> {% trans 'register' %}</button>
<button type="reset"><span class="fa fa-undo"></span> {% trans 'reset' %}</button>
<button type="submit"><span class="fa fa-user-plus"></span> {% trans 'register' %}</button>
</p>
</div>
</form>
{% endblock %}

View File

@@ -83,7 +83,7 @@ class MembershipDetail(mixins.LoginRequiredMixin, generic.DetailView):
if self.kwargs.get('username'):
return models.Membership.objects.get(username=self.kwargs['username'])
elif self.request.user.is_authenticated():
return models.Membership.objects.get(user=self.request.user)
return self.request.user
except models.Membership.DoesNotExist:
raise Http404(_("No %(verbose_name)s found matching the query") %
{'verbose_name': self.model._meta.verbose_name})
@@ -92,15 +92,15 @@ class MembershipDetail(mixins.LoginRequiredMixin, generic.DetailView):
context = generic.DetailView.get_context_data(self, **kwargs)
try:
context['kyu_dan_ranking'] = KyuDanRanking.objects.get(
user_id=self.object.user_id)
user=self.object)
except KyuDanRanking.DoesNotExist:
context['kyu_dan_ranking'] = None
try:
context['ladder_ranking'] = LadderRanking.objects.get(
user_id=self.object.user_id,
user=self.object,
season=LadderSeason.objects.current())
except LadderRanking.DoesNotExist:
context['ladder_ranking'] = LadderRanking(user=self.object.user)
context['ladder_ranking'] = LadderRanking(user=self.object)
return context