Skip to content
Snippets Groups Projects
Unverified Commit 293e5ea4 authored by Thom Wiggers's avatar Thom Wiggers :triangular_ruler:
Browse files

Introduce admin page, fix a couple of bugs

parent 4a1b5c7a
No related branches found
No related tags found
No related merge requests found
......@@ -10,7 +10,7 @@ commands =
deps = -r{toxinidir}/requirements.txt
[flake8]
exclude = */migrations/*, */urls.py
exclude = */migrations/*, */urls.py, */.ropeproject/*
[testenv:flake8]
deps=flake8
......
# Register your models here.
"""
This module registers admin pages for the models
"""
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from . import models
class MemberInline(admin.StackedInline):
model = models.Member
can_delete = False
class UserAdmin(BaseUserAdmin):
inlines = (MemberInline,)
# FIXME include proper filter for expiration
# https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
list_filter = ('member__type',
'member__membership_expiration',
'is_superuser')
# FIXME use nicer form
# form = forms.AdminForm (base on ModelForm, reorder elements, etc).
# re-register User admin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
# -*- coding: utf-8 -*-
# Generated by Django 1.10b1 on 2016-06-29 22:49
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Membership',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('membership_type', models.CharField(choices=[('benefactor', 'Benefactor'), ('member', 'Member'), ('honorary', 'Honorary Member')], max_length=40)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10b1 on 2016-07-06 13:32
from __future__ import unicode_literals
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import localflavor.generic.models
class Migration(migrations.Migration):
replaces = [('members', '0001_initial'), ('members', '0002_auto_20160706_1411'), ('members', '0003_auto_20160706_1424'), ('members', '0004_auto_20160706_1532')]
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Member',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('programme', models.CharField(blank=True, choices=[('computingscience', 'Computing Science'), ('informationscience', 'Information Sciences')], max_length=20, null=True, verbose_name='Study programme')),
('student_number', models.CharField(blank=True, max_length=8, null=True, validators=[django.core.validators.RegexValidator(message='Enter a valid student- of e/z/u-number.', regex='(s\\d{7}|[ezu]\\d{6,7})')])),
('type', models.CharField(choices=[('benefactor', 'Benefactor'), ('member', 'Member'), ('honorary', 'Honorary Member')], max_length=40, verbose_name='Membership type')),
('registration_year', models.IntegerField(help_text='The year this member first became a part of Thalia', verbose_name='Registration year')),
('membership_expiration', models.DateField(blank=True, help_text='Let the membership expire after this time', null=True, verbose_name='Expiration date of membership')),
('address_street', models.CharField(max_length=100, null=True, validators=[django.core.validators.RegexValidator(message='Include the house number', regex='^.+ \\d+.+')], verbose_name='Street and house number')),
('address_street2', models.CharField(blank=True, max_length=100, null=True, verbose_name='Second address line')),
('address_postal_code', models.CharField(max_length=10, null=True, verbose_name='Postal code')),
('address_city', models.CharField(max_length=40, null=True, verbose_name='City')),
('phone_number', models.CharField(blank=True, help_text='Enter a phone number so Thalia may reach you', max_length=13, null=True, validators=[django.core.validators.RegexValidator(message='Please enter a valid phone number', regex='^\\+?\\d+$')], verbose_name='Phone number')),
('birthday', models.DateField(null=True, verbose_name='Birthday')),
('website', models.URLField(blank=True, help_text='Website to display on your profile page', null=True, verbose_name='Website')),
('profile_description', models.TextField(blank=True, help_text='Text to display on your profile', verbose_name='Profile text')),
('nickname', models.CharField(blank=True, max_length=30, null=True, verbose_name='Nickname')),
('language', models.CharField(choices=[('en', 'English'), ('nl', 'Dutch')], default='nl', help_text='Preferred language for e.g. news letters', max_length=5, verbose_name='Preferred language')),
('receive_optin', models.BooleanField(default=True, help_text="Receive mailings about vacancies and events from Thalia's sponsors.", verbose_name='Receive opt-in mailings')),
('direct_debit_authorized', models.BooleanField(choices=[(True, 'Yes, I want Thalia to take the membership fees from my bank account through direct debit for each year.'), (False, 'No, I will pay the contribution myself')], default=False, help_text='Each year, have Thalia take the membership fees from my bank account', verbose_name='Direct debit')),
('bank_account', localflavor.generic.models.IBANField(False, ('AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GI', 'GR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK', 'SM'), blank=True, help_text='Bank account for direct debit', verbose_name='Bank account')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('display_name_preference', models.CharField(choices=[('full', 'Show full name'), ('nickname', 'Show only nickname'), ('initials', 'Show initials and last name'), ('fullnick', 'Show name like "John \'nickname\' Doe"'), ('nicklast', 'Show nickname and last name')], default='full', max_length=10, verbose_name='How to display name')),
('emergency_contact', models.CharField(blank=True, help_text='Who should we contact in case of emergencies', max_length=255, null=True, verbose_name='Emergency contact name')),
('emergency_contact_phone_number', models.CharField(blank=True, help_text='The phone number for the emergency contact', max_length=13, null=True, validators=[django.core.validators.RegexValidator(message='Voer een geldig telefoonnummer in.', regex='^\\+?\\d+$')], verbose_name='Emergency contact phone number')),
('show_birthday', models.BooleanField(default=True, help_text='Show the birthday on your profile page and in the birthday calendar', verbose_name='Display birthday')),
],
),
]
from datetime import datetime
import datetime
from django.db import models
from django.core import validators
......@@ -46,7 +46,7 @@ class Member(models.Model):
null=True,
)
membership_type = models.CharField(
type = models.CharField(
max_length=40,
choices=MEMBERSHIP_TYPES,
verbose_name=_('Membership type'),
......@@ -55,7 +55,6 @@ class Member(models.Model):
registration_year = models.IntegerField(
verbose_name=_('Registration year'),
help_text=_('The year this member first became a part of Thalia'),
default=lambda: datetime.utcnow().year,
)
membership_expiration = models.DateField(
......@@ -102,47 +101,26 @@ class Member(models.Model):
help_text=_('Enter a phone number so Thalia may reach you'),
validators=[validators.RegexValidator(
regex=r'^\+?\d+$',
message=_('Voer een geldig telefoonnummer in.'),
message=_('Please enter a valid phone number'),
)],
null=True,
blank=True,
)
# ---- Parents' address ----
# ---- Emergency contact ----
parent_address_street = models.CharField(
max_length=100,
validators=[validators.RegexValidator(
regex=r'^.+ \d+.+',
message=_('Include the house number'),
)],
verbose_name=_('Street and house number'),
emergency_contact = models.CharField(
max_length=255,
verbose_name=_('Emergency contact name'),
help_text=_('Who should we contact in case of emergencies'),
null=True,
)
parent_address_street2 = models.CharField(
max_length=100,
verbose_name=_('Second address line'),
blank=True,
null=True,
)
parent_address_postal_code = models.CharField(
max_length=10,
verbose_name=_('Postal code'),
null=True,
)
parent_address_city = models.CharField(
max_length=40,
verbose_name=_('City'),
null=True,
)
parent_phone_number = models.CharField(
emergency_contact_phone_number = models.CharField(
max_length=13,
verbose_name=_('Phone number'),
help_text=_('Enter a phone number so Thalia may reach you'),
verbose_name=_('Emergency contact phone number'),
help_text=_('The phone number for the emergency contact'),
validators=[validators.RegexValidator(
regex=r'^\+?\d+$',
message=_('Voer een geldig telefoonnummer in.'),
......@@ -158,6 +136,14 @@ class Member(models.Model):
null=True
)
show_birthday = models.BooleanField(
verbose_name=_('Display birthday'),
help_text=_(
'Show the birthday on your profile page and '
'in the birthday calendar'),
default=True,
)
website = models.URLField(
max_length=200,
verbose_name=_('Website'),
......@@ -169,6 +155,7 @@ class Member(models.Model):
profile_description = models.TextField(
verbose_name=_('Profile text'),
help_text=_('Text to display on your profile'),
blank=True,
)
nickname = models.CharField(
......@@ -178,6 +165,17 @@ class Member(models.Model):
null=True,
)
display_name_preference = models.CharField(
max_length=10,
verbose_name=_('How to display name'),
choices=(('full', _('Show full name')),
('nickname', _('Show only nickname')),
('initials', _('Show initials and last name')),
('fullnick', _("Show name like \"John 'nickname' Doe\"")),
('nicklast', _("Show nickname and last name"))),
default='full',
)
# --- Communication preference ----
language = models.CharField(
......@@ -210,5 +208,34 @@ class Member(models.Model):
bank_account = IBANField(
verbose_name=_('Bank account'),
include_countries=IBAN_SEPA_COUNTRIES
help_text=_('Bank account for direct debit'),
include_countries=IBAN_SEPA_COUNTRIES,
blank=True,
)
def is_active(self):
"""Is this member currently active
Tested by checking if the expiration date has passed.
"""
return self.membership_expiration < datetime.utcnow()
# Special properties for admin site
is_active.boolean = True
is_active.short_description = _('Is this user currently active')
def display_name(self):
pref = self.display_name_preference
if pref == 'nickname':
return self.nickname
elif pref == 'initials':
return '{} {}'.format(self.initials, self.user.last_name)
elif pref == 'fullnick':
return "{} '{}' {}".format(self.user.first_name,
self.nickname,
self.user.last_name)
elif pref == 'nicklast':
return "'{}' {}".format(self.nickname,
self.user.last_name)
else:
return self.user.full_name()
display_name.short_description = _('Display name')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment