mirror of
https://github.com/fspc/workstand.git
synced 2025-02-23 09:13:23 -05:00
Add members to Mailchimp list with interests (#59)
This commit is contained in:
parent
38ab5694bc
commit
624ec2ed88
@ -53,4 +53,7 @@ MIDDLEWARE_CLASSES.insert(0, 'django.middleware.common.CommonMiddleware') # noq
|
|||||||
|
|
||||||
CORS_ORIGIN_ALLOW_ALL = True
|
CORS_ORIGIN_ALLOW_ALL = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['workstand.docker','localhost']
|
ALLOWED_HOSTS = ['workstand.docker', 'localhost']
|
||||||
|
|
||||||
|
MAILCHIMP_API_KEY = '78ee4eb990c5646256aac6c3b6a4e966-us7'
|
||||||
|
MAILCHIMP_USERNAME = 'drew@bcbc.bike'
|
||||||
|
@ -65,3 +65,5 @@ ROLLBAR = {
|
|||||||
|
|
||||||
rollbar.init(**ROLLBAR)
|
rollbar.init(**ROLLBAR)
|
||||||
|
|
||||||
|
MAILCHIMP_API_KEY = 'c6bba083fb5adc45a317dfb149d3676a-us7'
|
||||||
|
MAILCHIMP_USERNAME = 'drew@bcbc.bike'
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
default_app_config = 'registration.apps.RegistrationConfig'
|
@ -3,3 +3,7 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
class RegistrationConfig(AppConfig):
|
class RegistrationConfig(AppConfig):
|
||||||
name = 'registration'
|
name = 'registration'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
import registration.handlers
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from django.forms import ModelForm, EmailInput, TextInput, DateInput, CheckboxInput, BooleanField, Textarea, DateField
|
from django.forms import ModelForm, EmailInput, TextInput, DateInput, CheckboxInput, BooleanField, Textarea, DateField, CheckboxSelectMultiple
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from registration.models import Member
|
from registration.models import Member
|
||||||
|
|
||||||
@ -18,12 +18,14 @@ class MemberForm(ModelForm):
|
|||||||
exclude = ('waiver',)
|
exclude = ('waiver',)
|
||||||
fields = ['email', 'email_consent', 'first_name', 'last_name', 'preferred_name', 'date_of_birth',
|
fields = ['email', 'email_consent', 'first_name', 'last_name', 'preferred_name', 'date_of_birth',
|
||||||
'guardian_name', 'phone', 'street', 'city', 'province', 'country', 'post_code', 'waiver',
|
'guardian_name', 'phone', 'street', 'city', 'province', 'country', 'post_code', 'waiver',
|
||||||
'banned', 'suspended', 'notes']
|
'banned', 'suspended', 'notes', 'involvement']
|
||||||
widgets = {
|
widgets = {
|
||||||
'email': EmailInput(attrs={'class': 'mdl-textfield__input'}),
|
'email': EmailInput(attrs={'class': 'mdl-textfield__input'}),
|
||||||
'email_consent': CheckboxInput(attrs={'class': 'mdl-checkbox__input'}),
|
'email_consent': CheckboxInput(attrs={'class': 'mdl-checkbox__input'}),
|
||||||
'first_name': TextInput(attrs={'class': 'mdl-textfield__input'}),
|
'first_name': TextInput(attrs={'class': 'mdl-textfield__input'}),
|
||||||
'last_name': TextInput(attrs={'class': 'mdl-textfield__input'}),
|
'last_name': TextInput(attrs={'class': 'mdl-textfield__input'}),
|
||||||
|
'involvement': CheckboxSelectMultiple(choices=Member.involvement_choices,
|
||||||
|
attrs={'class': 'mdl-checkbox__input'}),
|
||||||
'preferred_name': TextInput(attrs={'class': 'mdl-textfield__input'}),
|
'preferred_name': TextInput(attrs={'class': 'mdl-textfield__input'}),
|
||||||
'guardian_name': DateInput(attrs={'class': 'mdl-textfield__input', 'disabled': 'disabled'}),
|
'guardian_name': DateInput(attrs={'class': 'mdl-textfield__input', 'disabled': 'disabled'}),
|
||||||
'phone': TextInput(attrs={'class': 'mdl-textfield__input', 'pattern': '[0-9]*'}),
|
'phone': TextInput(attrs={'class': 'mdl-textfield__input', 'pattern': '[0-9]*'}),
|
||||||
|
30
bikeshop_project/registration/handlers.py
Normal file
30
bikeshop_project/registration/handlers.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import hashlib
|
||||||
|
|
||||||
|
from django.db.models.signals import post_save
|
||||||
|
from django.dispatch import receiver
|
||||||
|
from django.conf import settings
|
||||||
|
from mailchimp3 import MailChimp
|
||||||
|
from requests import HTTPError
|
||||||
|
|
||||||
|
from registration.models import Member
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=Member, dispatch_uid='member.save_member')
|
||||||
|
def update_mailchimp(sender, instance, **kwargs):
|
||||||
|
if instance.email:
|
||||||
|
involvement = {id: True for id in instance.involvement}
|
||||||
|
client = MailChimp(settings.MAILCHIMP_USERNAME, settings.MAILCHIMP_API_KEY)
|
||||||
|
try:
|
||||||
|
response = client.lists.members.create_or_update('1c664549e2',
|
||||||
|
hashlib.md5(bytes(instance.email, 'utf-8')).hexdigest(), {
|
||||||
|
'email_address': instance.email,
|
||||||
|
'status': 'subscribed' if instance.email_consent else 'unsuscribed',
|
||||||
|
'status_if_new': 'subscribed' if instance.email_consent else 'unsuscribed',
|
||||||
|
'merge_fields': {
|
||||||
|
'FNAME': instance.first_name,
|
||||||
|
'LNAME': instance.last_name,
|
||||||
|
},
|
||||||
|
'interests': involvement
|
||||||
|
})
|
||||||
|
except HTTPError as error:
|
||||||
|
pass
|
@ -0,0 +1,28 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.4 on 2017-05-28 23:39
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import multiselectfield.db.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('registration', '0004_auto_20170518_0332'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='involvement',
|
||||||
|
field=multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('ac6922146d', 'General (receive email)'), ('3a5a719017', 'Volunteering'), ('0ebb0b5468', 'Events'), ('84309225e7', 'Workshops'), ('c96d389517', 'Shop')], max_length=54, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='user',
|
||||||
|
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
@ -1,6 +1,7 @@
|
|||||||
from django.contrib.auth.models import (AbstractBaseUser, BaseUserManager,
|
from django.contrib.auth.models import (AbstractBaseUser, BaseUserManager,
|
||||||
PermissionsMixin)
|
PermissionsMixin)
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from multiselectfield import MultiSelectField
|
||||||
|
|
||||||
|
|
||||||
class CustomUserManager(BaseUserManager):
|
class CustomUserManager(BaseUserManager):
|
||||||
@ -70,8 +71,16 @@ class CustomUser(AbstractBaseUser, PermissionsMixin):
|
|||||||
|
|
||||||
|
|
||||||
class Member(models.Model):
|
class Member(models.Model):
|
||||||
|
involvement_choices = (
|
||||||
|
('21cd9799b6', 'General (receive email)'),
|
||||||
|
('3a5a719017', 'Volunteering'),
|
||||||
|
('0ebb0b5468', 'Events'),
|
||||||
|
('84309225e7', 'Workshops'),
|
||||||
|
('c96d389517', 'Shop'),
|
||||||
|
)
|
||||||
|
|
||||||
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE,
|
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE,
|
||||||
null=True)
|
null=True, blank=True)
|
||||||
email = models.EmailField(
|
email = models.EmailField(
|
||||||
verbose_name='email address',
|
verbose_name='email address',
|
||||||
max_length=255,
|
max_length=255,
|
||||||
@ -98,6 +107,7 @@ class Member(models.Model):
|
|||||||
banned = models.BooleanField(default=False)
|
banned = models.BooleanField(default=False)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
modified_at = models.DateTimeField(auto_now=True)
|
modified_at = models.DateTimeField(auto_now=True)
|
||||||
|
involvement = MultiSelectField(choices=involvement_choices, null=True, blank=True)
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
# The user is identified by their email address
|
# The user is identified by their email address
|
||||||
|
@ -63,11 +63,21 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="{{ form.email_consent.id_for_label }}">
|
<h3 class="template__header mdl-typography--body-2">Involvement</h3>
|
||||||
{{ form.email_consent }}
|
{% for checkbox in form.involvement %}
|
||||||
<span class="mdl-checkbox__label">{{ form.email_consent.label }}</span>
|
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="{{ checkbox.id_for_label }}">
|
||||||
</label>
|
{{ checkbox }}
|
||||||
</div>
|
<span class="mdl-checkbox__label">{{ checkbox.label }}</span>
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="template__header mdl-typography--body-2">Receive Email</h3>
|
||||||
|
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="{{ form.email_consent.id_for_label }}">
|
||||||
|
{{ form.email_consent }}
|
||||||
|
<span class="mdl-checkbox__label">{{ form.email_consent.label }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -86,8 +86,18 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<span class="mdl-textfield__error">Invalid email.</span>
|
<span class="mdl-textfield__error">Invalid email.</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="template__header mdl-typography--body-2">Involvement</h3>
|
||||||
|
{% for checkbox in form.involvement %}
|
||||||
|
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="{{ checkbox.id_for_label }}">
|
||||||
|
{{ checkbox }}
|
||||||
|
<span class="mdl-checkbox__label">{{ checkbox.label }}</span>
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
<h3 class="template__header mdl-typography--body-2">Receive Email</h3>
|
||||||
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="{{ form.email_consent.id_for_label }}">
|
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="{{ form.email_consent.id_for_label }}">
|
||||||
{{ form.email_consent }}
|
{{ form.email_consent }}
|
||||||
<span class="mdl-checkbox__label">{{ form.email_consent.label }}</span>
|
<span class="mdl-checkbox__label">{{ form.email_consent.label }}</span>
|
||||||
|
@ -83,8 +83,8 @@ class TestMemberSearchView(TestCase):
|
|||||||
if self.query in result['name']])
|
if self.query in result['name']])
|
||||||
|
|
||||||
def test_search_name_with_space(self):
|
def test_search_name_with_space(self):
|
||||||
mommy.make(Member, first_name="Test", last_name="Person")
|
mommy.make(Member, first_name="Some", last_name="Thing")
|
||||||
url = reverse('member_search', kwargs=dict(query='Test Person'))
|
url = reverse('member_search', kwargs=dict(query='Some Th'))
|
||||||
c = Client()
|
c = Client()
|
||||||
c.force_login(self.user)
|
c.force_login(self.user)
|
||||||
response = c.get(url)
|
response = c.get(url)
|
||||||
@ -96,7 +96,7 @@ class TestMemberSearchView(TestCase):
|
|||||||
|
|
||||||
# Check if our made up first name is in the name returned.
|
# Check if our made up first name is in the name returned.
|
||||||
self.assertTrue([result['name'] for result in results
|
self.assertTrue([result['name'] for result in results
|
||||||
if 'Test Person' in result['name']])
|
if 'Some Thing' in result['name']])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,4 +11,6 @@ djangorestframework
|
|||||||
django-webpack-loader
|
django-webpack-loader
|
||||||
requests
|
requests
|
||||||
PyYAML
|
PyYAML
|
||||||
djangorestframework-jwt==1.9.0
|
djangorestframework-jwt==1.9.0
|
||||||
|
django-multiselectfield==0.1.4
|
||||||
|
mailchimp3==2.0.11
|
||||||
|
Loading…
x
Reference in New Issue
Block a user