diff --git a/OACPL/settings.base.py b/OACPL/settings.base.py
index 10ff7c6..32fa383 100644
--- a/OACPL/settings.base.py
+++ b/OACPL/settings.base.py
@@ -53,7 +53,8 @@ INSTALLED_APPS = [
'forum.apps.ForumConfig',
'main.apps.MainConfig',
'newsletters.apps.NewslettersConfig',
- 'tinymce'
+ 'tinymce',
+ 'widget_tweaks'
]
MIDDLEWARE = [
diff --git a/charter_members/admin.py b/charter_members/admin.py
index f284b3c..1c458d4 100644
--- a/charter_members/admin.py
+++ b/charter_members/admin.py
@@ -1,16 +1,16 @@
from django.contrib import admin
-from .models import Chapter, Position, Attorney
+from .models import Region, Position, Attorney
-admin.site.register(Chapter)
+admin.site.register(Region)
admin.site.register(Position)
@admin.register(Attorney)
class MemberAdmin(admin.ModelAdmin):
- list_display = ['name', 'position', 'chapter', 'phone_formatted', 'email', 'front_page', 'order', 'joined', 'thumbnail']
- list_filter = ['chapter', 'position', 'front_page', 'joined']
- search_fields = ['email', 'joined', 'name', 'chapter', 'position', 'website', 'phone', 'phone_formatted']
- fields = ['image_preview', 'image', 'name', 'position', 'chapter', 'biography', 'phone', 'email', 'website', 'front_page', 'order', 'joined']
+ list_display = ['last_name', 'first_name', 'position', 'region', 'phone_formatted', 'email', 'front_page', 'order', 'joined', 'thumbnail']
+ list_filter = ['region', 'position', 'front_page', 'joined']
+ search_fields = ['email', 'joined', 'last_name', 'first_name', 'region', 'position', 'website', 'phone', 'phone_formatted']
+ fields = ['image_preview', 'image', 'last_name', 'first_name', 'position', 'region', 'biography', 'phone', 'email', 'website', 'front_page', 'order', 'joined']
readonly_fields = ['image_preview']
diff --git a/charter_members/forms.py b/charter_members/forms.py
new file mode 100644
index 0000000..fefc3d9
--- /dev/null
+++ b/charter_members/forms.py
@@ -0,0 +1,78 @@
+from django.core import mail
+from django import forms
+from django.contrib.auth.models import Group, User
+
+from tinymce import TinyMCE
+
+from newsletters.models import Subscriber
+from .models import Attorney, Position
+from OACPL import settings
+from OACPL.utils import render_to_string
+
+
+class RegisterForm(forms.ModelForm):
+ def email_validator(self):
+ if User.objects.filter(email=self).exists():
+ raise forms.ValidationError('This email is already registered')
+
+ def password_length(self):
+ if len(self) < 8:
+ raise forms.ValidationError('Password must be at least 8 characters long')
+
+ biography = forms.CharField(widget=forms.Textarea, required=False, label='Biography')
+ call_to_bar = forms.CharField(max_length=4, required=False, label='Year of Call to Bar')
+ case_law = forms.BooleanField(initial=True, required=False)
+ email = forms.EmailField(max_length=255, validators=[email_validator])
+ lso = forms.CharField(max_length=20, required=False, label='LSO #')
+ newsletter = forms.BooleanField(initial=True, required=False)
+ request_training = forms.CharField(max_length=255, required=False, label='Request Training For...')
+ password1 = forms.CharField(widget=forms.PasswordInput(), validators=[password_length])
+ password2 = forms.CharField(widget=forms.PasswordInput())
+ provide_training = forms.CharField(max_length=255, required=False, label='Offer Training For...')
+
+ class Meta:
+ model = Attorney
+ fields = ['first_name', 'last_name', 'region', 'password1', 'password2', 'image', 'email', 'address', 'phone', 'website', 'call_to_bar', 'lso', 'biography', 'provide_training', 'request_training', 'case_law', 'newsletter']
+
+ def clean(self):
+ cleaned_data = super().clean()
+ password = cleaned_data.get('password1')
+ password_confirm = cleaned_data.get('password2')
+ if password != password_confirm:
+ raise forms.ValidationError("The two password fields must match.")
+ return cleaned_data
+
+ def save(self, commit=True):
+ # Create attorney profile
+ user = super().save(commit=False)
+ member = Position.objects.filter(name='Member').first()
+ if member:
+ user.position = member
+ user.save()
+
+ # Add user to default Group
+ default_group = Group.objects.filter(name='default').first()
+ if default_group:
+ default_group[0].user_set.add(user)
+
+ # Send confirmation email
+ mail.send_mail('OACPL Registration', 'You have successfully registered to the Ontario Association of Child Protection Lawyers!', settings.EMAIL_HOST_USER, [user.email], html_message=render_to_string('email.html', {'content': 'You have successfully registered to the Ontario Association of Child Protection Lawyers!', 'name': user.first_name + ' ' + user.last_name, 'base_url': settings.BASE_URL}))
+
+ # Subscribe to newsletters
+ if self.cleaned_data['newsletter'] == 'on' and not Subscriber.objects.filter(email=user.email).exists():
+ Subscriber.objects.create(email=user.email)
+
+ # Send email to register@oacpl.org
+ body = '{} {} ({}) has registered with OACPL.
'.format(user.first_name, user.last_name, user.email)
+ if self.cleaned_data['case_law'] == 'on':
+ body += 'They have request access to case law.
'
+ if self.cleaned_data['provide_training']:
+ body += 'They have offered to provide training for: {}.
'.format(self.cleaned_data['provide_training'])
+ if self.cleaned_data['request_training']:
+ body += 'They have request training for: {}.
'.format(self.cleaned_data['request_training'])
+ mail.send_mail(user.first_name + ' ' + user.last_name, body.replace('
', ' '), settings.EMAIL_HOST_USER, ['register@oacpl.org'], html_message=render_to_string('email.html', {'content': body, 'base_url': settings.BASE_URL}))
+
+ # Create Auth
+ auth = User.objects.create_user(user.email, first_name=user.first_name, last_name=user.last_name, email=user.email, password=self.cleaned_data['password1'])
+ auth.save()
+ return auth
diff --git a/charter_members/models.py b/charter_members/models.py
index b8a898b..72ab97f 100644
--- a/charter_members/models.py
+++ b/charter_members/models.py
@@ -1,10 +1,11 @@
from django.conf import settings
from django.db import models
+from django.utils import timezone
from tinymce import HTMLField
-class Chapter(models.Model):
+class Region(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
@@ -12,23 +13,27 @@ class Chapter(models.Model):
class Position(models.Model):
- position_name = models.CharField(max_length=50)
+ name = models.CharField(max_length=50)
def __str__(self):
- return self.position_name
+ return self.name
class Attorney(models.Model):
+ address = models.CharField(max_length=255)
biography = HTMLField(blank=True, null=True)
- chapter = models.ForeignKey(Chapter, blank=True, null=True)
- email = models.CharField(max_length=255, blank=True, null=True)
+ call_to_bar = models.CharField(max_length=4, blank=True, null=True)
+ region = models.ForeignKey(Region, blank=True, null=True)
+ email = models.CharField(max_length=255)
+ first_name = models.CharField(max_length=100)
front_page = models.BooleanField(default=False)
image = models.ImageField(upload_to='portraits', default='portraits/silhouette.png')
- joined = models.DateField(blank=True, null=True)
- name = models.CharField(max_length=100)
+ joined = models.DateField(default=timezone.now)
+ last_name = models.CharField(max_length=100)
+ lso = models.CharField(max_length=20, blank= True, null=True)
order = models.IntegerField(blank=True, null=True, verbose_name='Order On Front Page')
- phone = models.CharField(max_length=10, blank=True, null=True)
- position = models.ForeignKey(Position)
+ phone = models.CharField(max_length=10)
+ position = models.ForeignKey(Position, blank=True, null=True)
website = models.CharField(max_length=255, blank=True, null=True)
def phone_formatted(self):
@@ -47,4 +52,4 @@ class Attorney(models.Model):
image_preview.allow_tags = True
def __str__(self):
- return self.name
+ return self.first_name + ' ' + self.last_name
diff --git a/charter_members/templates/all.html b/charter_members/templates/all.html
index ed0316e..b335ef9 100644
--- a/charter_members/templates/all.html
+++ b/charter_members/templates/all.html
@@ -3,19 +3,19 @@
{% block body %}
{{ attorney.biography | safe }}