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 %}
- {% for chapter in chapters %} + {% for region in region %}
-

{{ chapter }}

+

{{ region }}


{% for attorney in attorneys %} - {% if attorney.chapter == chapter %} + {% if attorney.region == region %}
-
{{ attorney.name }}
+
{{ attorney.first_name }} {{ attorney.last_name }}
{{ attorney.position }}
diff --git a/charter_members/templates/attorney.html b/charter_members/templates/attorney.html index e2e936f..f2aed9a 100644 --- a/charter_members/templates/attorney.html +++ b/charter_members/templates/attorney.html @@ -4,7 +4,7 @@
-

{{ attorney.name }}

+

{{ attorney.first_name }} {{ attorney.last_name }}

@@ -14,7 +14,7 @@
-

{{ attorney.name }}

+

{{ attorney.first_name }} {{ attorney.last_name }}

{{ attorney.biography | safe }}

diff --git a/charter_members/views.py b/charter_members/views.py index 56983af..83be897 100644 --- a/charter_members/views.py +++ b/charter_members/views.py @@ -1,7 +1,7 @@ from django.db.models import Count from django.shortcuts import render -from .models import Chapter, Attorney +from .models import Region, Attorney def index(request, id): @@ -10,6 +10,6 @@ def index(request, id): def all(request): - chapters = Chapter.objects.all().order_by('name') - attorneys = Attorney.objects.all().annotate(Count('chapter')) - return render(request, 'all.html', {'chapters': chapters, 'attorneys': attorneys}) + region = Region.objects.all().order_by('name') + attorneys = Attorney.objects.all().annotate(Count('region')) + return render(request, 'all.html', {'region': region, 'attorneys': attorneys}) diff --git a/main/templates/index.html b/main/templates/index.html index 8072a1e..6c11bbc 100644 --- a/main/templates/index.html +++ b/main/templates/index.html @@ -141,7 +141,7 @@
-
{{ attorney.name }}
+
{{ attorney.first_name }} {{ attorney.last_name }}
{{ attorney.position }}
diff --git a/main/templates/login.html b/main/templates/login.html index 4a182a3..0a54f6b 100644 --- a/main/templates/login.html +++ b/main/templates/login.html @@ -1,5 +1,6 @@ {% extends 'base.html' %} {% load static %} +{% load widget_tweaks %} {% block head %} {% endblock %} {% block body %} -