Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation to EventApplication model #576

Merged
merged 13 commits into from May 10, 2021
9 changes: 8 additions & 1 deletion core/validators.py
Expand Up @@ -3,6 +3,9 @@
from django.core.exceptions import ValidationError


today = date.today()


def validate_approximatedate(e_date):
if e_date.month == 0:
raise ValidationError(
Expand All @@ -12,7 +15,11 @@ def validate_approximatedate(e_date):


def validate_event_date(e_date):
today = date.today()
if date(e_date.year, e_date.month, e_date.day) - today < timedelta(days=90):
raise ValidationError('Your event date is too close. '
'Workshop date should be at least 3 months (90 days) from now.')


def validate_future_date(e_date):
if date(e_date.year, e_date.month, e_date.day) - today < timedelta(days=0):
raise ValidationError('Event date should be in the future')
2 changes: 2 additions & 0 deletions organize/admin.py
Expand Up @@ -60,6 +60,7 @@ class EventApplicationAdmin(admin.ModelAdmin):
'coaches',
'remote',
'tools',
'diversity',
'safety',
'additional'
)
Expand Down Expand Up @@ -101,6 +102,7 @@ class EventApplicationAdmin(admin.ModelAdmin):
'remote',
'tools',
'safety',
'diversity',
'additional'
],
'classes': ('suit-tab', 'suit-tab-application',)
Expand Down
12 changes: 11 additions & 1 deletion organize/forms.py
Expand Up @@ -4,7 +4,7 @@
from django_date_extensions.fields import ApproximateDateFormField

from core.models import Event
from core.validators import validate_approximatedate, validate_event_date
from core.validators import validate_approximatedate, validate_event_date, validate_future_date
from .constants import INVOLVEMENT_CHOICES

PREVIOUS_ORGANIZER_CHOICES = (
Expand Down Expand Up @@ -115,6 +115,9 @@ class WorkshopForm(forms.Form):
safety = forms.CharField(
widget=forms.Textarea(attrs={'class': 'compact-input'})
)
diversity = forms.CharField(
widget=forms.Textarea(attrs={'class': 'compact-input'})
)
additional = forms.CharField(
widget=forms.Textarea(attrs={'class': 'compact-input'})
)
Expand All @@ -123,6 +126,8 @@ def clean_date(self):
date = self.cleaned_data.get('date')
validate_approximatedate(date)
# Check if the event is in the future
validate_future_date(date)
# Check if date is 3 months away
validate_event_date(date)
return date

Expand All @@ -146,6 +151,9 @@ class RemoteWorkshopForm(forms.Form):
tools = forms.CharField(
widget=forms.Textarea(attrs={'class': 'compact-input'})
)
diversity = forms.CharField(
widget=forms.Textarea(attrs={'class': 'compact-input'})
)
additional = forms.CharField(
widget=forms.Textarea(attrs={'class': 'compact-input'})
)
Expand All @@ -154,6 +162,8 @@ def clean_date(self):
date = self.cleaned_data.get('date')
validate_approximatedate(date)
# Check if the event is in the future
validate_future_date(date)
# Check if date is 3 months away
validate_event_date(date)
return date

Expand Down
19 changes: 19 additions & 0 deletions organize/migrations/0006_eventapplication_diversity.py
@@ -0,0 +1,19 @@
# Generated by Django 2.0.12 on 2021-01-18 23:46

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('organize', '0005_eventapplication_additional'),
]

operations = [
migrations.AddField(
model_name='eventapplication',
name='diversity',
field=models.TextField(default='', verbose_name='Information about how you intend to ensure your workshop is inclusive and promotes diversity'),
preserve_default=False,
),
]
39 changes: 39 additions & 0 deletions organize/models.py
@@ -1,8 +1,11 @@
from datetime import date, datetime, timedelta

from django.core.exceptions import ValidationError
from django_countries import countries
from django_extensions.db.fields import AutoSlugField
from django.db import models, transaction
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django_date_extensions.fields import ApproximateDateField

from core import gmail_accounts
Expand All @@ -26,6 +29,38 @@
)


class EventApplicationManager(models.Manager):

def create(self, **data_dict):
previous_application = EventApplication.objects.filter(
main_organizer_email=data_dict['main_organizer_email'],
status=NEW
).order_by('-created_at').first()

if previous_application:
if date.today() - date(previous_application.created_at.year,
previous_application.created_at.month,
previous_application.created_at.day) < timedelta(days=180):
raise ValidationError({'date': _('You cannot apply to organize another event when you '
'already have another open event application.')})

previous_event = EventApplication.objects.filter(
main_organizer_email=data_dict['main_organizer_email'],
status=DEPLOYED
).order_by('-date').first()

if previous_event:
event_date = datetime.strptime(data_dict['date'], '%Y-%m-%d')
if date(event_date.year,
event_date.month,
event_date.day) - date(previous_event.date.year,
previous_event.date.month,
previous_event.date.day) < timedelta(days=180):
raise ValidationError({'date': _('Your workshops should be at least 6 months apart. '
'Please read our Organizer Manual.')})
return super().create(**data_dict)


class EventApplication(models.Model):
previous_event = models.ForeignKey(Event, null=True, blank=True,
on_delete=models.deletion.SET_NULL)
Expand Down Expand Up @@ -57,6 +92,8 @@ class EventApplication(models.Model):
safety = models.TextField("Information about how you will ensure participants' and coaches' "
"safety during the Covid-19 pandemic",
blank=True)
diversity = models.TextField("Information about how you intend to ensure your workshop is inclusive "
"and promotes diversity")
additional = models.TextField("Any additional information you think may help your application",
blank=True)

Expand All @@ -70,6 +107,7 @@ class EventApplication(models.Model):

comment = models.TextField(null=True, blank=True)

object = EventApplicationManager()
objects = EventApplicationQuerySet.as_manager()

class Meta:
Expand All @@ -85,6 +123,7 @@ def __str__(self):
def save(self, *args, **kwargs):
if not self.latlng:
self.latlng = get_coordinates_for_city(self.city, self.get_country_display())

super(EventApplication, self).save(*args, **kwargs)

def create_event(self):
Expand Down
20 changes: 13 additions & 7 deletions organize/views.py
@@ -1,4 +1,6 @@
from formtools.wizard.views import NamedUrlSessionWizardView
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.shortcuts import redirect, render

from .emails import (
Expand Down Expand Up @@ -30,17 +32,21 @@ def get_template_names(self):
return [TEMPLATES[self.steps.current]]

def done(self, form_list, **kwargs):
# Process the date from the forms
# Process the data from the forms
data_dict = {}
for form in form_list:
data_dict.update(form.get_data_for_saving())

organizers_data = data_dict.pop('coorganizers', [])
application = EventApplication.objects.create(**data_dict)
for organizer in organizers_data:
application.coorganizers.create(**organizer)
send_application_confirmation(application)
send_application_notification(application)

try:
application = EventApplication.object.create(**data_dict)
for organizer in organizers_data:
application.coorganizers.create(**organizer)
send_application_confirmation(application)
send_application_notification(application)
except ValidationError as error:
messages.error(self.request, error.messages[0])
return redirect('organize:prerequisites')
return redirect('organize:form_thank_you')


Expand Down
2 changes: 1 addition & 1 deletion templates/core/donate.html
Expand Up @@ -96,7 +96,7 @@ <h4>Amazon Smile</h4>
contents.document.write(decodeURIComponent("%3Cdiv%20id%3D%22amznCharityBannerInner%22%3E%3Ca%20href%3D%22https%3A%2F%2Fsmile.amazon.co.uk%2Fch%2F1163260-0%22%20target%3D%22_blank%22%3E%3Cdiv%20class%3D%22text%22%20height%3D%22%22%3E%3Cdiv%20class%3D%22support-wrapper%22%3E%3Cdiv%20class%3D%22support%22%20style%3D%22font-size%3A%2025px%3B%20line-height%3A%2028px%3B%20margin-top%3A%201px%3B%20margin-bottom%3A%201px%3B%22%3ESupport%20%3Cspan%20id%3D%22charity-name%22%20style%3D%22display%3A%20inline-block%3B%22%3EDjango%20Girls%20Foundation%3C%2Fspan%3E%3C%2Fdiv%3E%3C%2Fdiv%3E%3Cp%20class%3D%22when-shop%22%3EWhen%20you%20shop%20at%20%3Cb%3Esmile.amazon.co.uk%2C%3C%2Fb%3E%3C%2Fp%3E%3Cp%20class%3D%22donates%22%3EAmazon%20Donates%3C%2Fp%3E%3C%2Fdiv%3E%3C%2Fa%3E%3C%2Fdiv%3E%3Cstyle%3E%23amznCharityBannerInner%7Bbackground-image%3Aurl(https%3A%2F%2Fm.media-amazon.com%2Fimages%2FG%2F02%2Fx-locale%2Fpaladin%2Fcharitycentral%2Fbanner-background-image._CB485923047_.png)%3Bwidth%3A302px%3Bheight%3A250px%3Bposition%3Arelative%7D%23amznCharityBannerInner%20a%7Bdisplay%3Ablock%3Bwidth%3A100%25%3Bheight%3A100%25%3Bposition%3Arelative%3Bcolor%3A%23000%3Btext-decoration%3Anone%7D.text%7Bposition%3Aabsolute%3Btop%3A20px%3Bleft%3A15px%3Bright%3A15px%3Bbottom%3A100px%7D.support-wrapper%7Boverflow%3Ahidden%3Bmax-height%3A86px%7D.support%7Bfont-family%3AArial%2Csans%3Bfont-weight%3A700%3Bline-height%3A28px%3Bfont-size%3A25px%3Bcolor%3A%23333%3Btext-align%3Acenter%3Bmargin%3A0%3Bpadding%3A0%3Bbackground%3A0%200%7D.when-shop%7Bfont-family%3AArial%2Csans%3Bfont-size%3A15px%3Bfont-weight%3A400%3Bline-height%3A25px%3Bcolor%3A%23333%3Btext-align%3Acenter%3Bmargin%3A0%3Bpadding%3A0%3Bbackground%3A0%200%7D.donates%7Bfont-family%3AArial%2Csans%3Bfont-size%3A15px%3Bfont-weight%3A400%3Bline-height%3A21px%3Bcolor%3A%23333%3Btext-align%3Acenter%3Bmargin%3A0%3Bpadding%3A0%3Bbackground%3A0%200%7D%3C%2Fstyle%3E")); contents.document.close(); iFrame.style.display = 'block';}); document.getElementById('amznCharityBanner').appendChild(iFrame); })();
</script>
</div>

</div>
</div>
</section>
Expand Down
18 changes: 18 additions & 0 deletions templates/organize/form/step5_workshop.html
Expand Up @@ -173,6 +173,24 @@ <h4 class="error">Please know that we are only accepting applications for remote
</ul>
</section>

<section class="form-section">
<label class="form-section-heading{% if form.diversity.field %} {% endif %}">How do you intent to make your workshop inclusive and promote diversity?</label>
<p class="form-section-subhead">Please tell us how you intend to make sure your workshop is inclusive to people from marginalised communities and promote diversity.</p>

<ul class="row">
<li class="col-sm-12 col-md-9">
{{ wizard.form.diversity }}
{% if wizard.form.diversity.errors %}
<ul class="error-list">
{% for error in wizard.form.diversity.errors %}
<li class="error">{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</li>
</ul>
</section>

<section class="form-section">
<label class="form-section-heading{% if form.additional.field %} {% endif %}">Any additional you may want to share with us?</label>
<p class="form-section-subhead">Please provide any additional information you may want to share with us and may think may help your application.</p>
Expand Down
18 changes: 18 additions & 0 deletions templates/organize/form/step5_workshop_remote.html
Expand Up @@ -153,6 +153,24 @@ <h1>Tell us all about your Django Girls event!</h1>
</ul>
</section>

<section class="form-section">
<label class="form-section-heading{% if form.diversity.field %} {% endif %}">How do you intent to make your workshop inclusive and promote diversity?</label>
<p class="form-section-subhead">Please tell us how you intend to make sure your workshop is inclusive to people from marginalised communities and promote diversity.</p>

<ul class="row">
<li class="col-sm-12 col-md-9">
{{ wizard.form.diversity }}
{% if wizard.form.diversity.errors %}
<ul class="error-list">
{% for error in wizard.form.diversity.errors %}
<li class="error">{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</li>
</ul>
</section>

<section class="form-section">
<label class="form-section-heading{% if form.additional.field %} {% endif %}">Any additional you may want to share with us?</label>
<p class="form-section-subhead">Please provide any additional information you may want to share with us and may think may help your application.</p>
Expand Down
8 changes: 8 additions & 0 deletions templates/organize/prerequisites.html
Expand Up @@ -17,6 +17,14 @@

<div class="row">
<div class="col-md-12">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% endif %}

<div class="panel">
<h1>Prerequisities to organize a Django Girls workshop</h1>

Expand Down