more program and schedule changes
This commit is contained in:
parent
518611534e
commit
201de12b49
|
@ -0,0 +1,2 @@
|
||||||
|
default_app_config = 'program.apps.ProgramConfig'
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.db.models.signals import m2m_changed, pre_save
|
||||||
|
from .signal_handlers import check_speaker_event_camp_consistency, check_speaker_camp_change
|
||||||
|
|
||||||
class ProgramConfig(AppConfig):
|
class ProgramConfig(AppConfig):
|
||||||
name = 'program'
|
name = 'program'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Speaker
|
||||||
|
m2m_changed.connect(check_speaker_event_camp_consistency, sender=Speaker.events.through)
|
||||||
|
pre_save.connect(check_speaker_camp_change, sender=Speaker)
|
||||||
|
|
||||||
|
|
22
program/migrations/0014_speaker_camp.py
Normal file
22
program/migrations/0014_speaker_camp.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-01-22 13:39
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('camps', '0017_remove_camp_description'),
|
||||||
|
('program', '0013_auto_20170121_1312'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='speaker',
|
||||||
|
name='camp',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='speakers', to='camps.Camp'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -90,6 +90,7 @@ class Speaker(CreatedUpdatedModel):
|
||||||
biography = models.TextField()
|
biography = models.TextField()
|
||||||
picture = models.ImageField(null=True, blank=True)
|
picture = models.ImageField(null=True, blank=True)
|
||||||
slug = models.SlugField(blank=True, max_length=255)
|
slug = models.SlugField(blank=True, max_length=255)
|
||||||
|
camp = models.ForeignKey('camps.Camp', null=True, related_name="speakers")
|
||||||
events = models.ManyToManyField(
|
events = models.ManyToManyField(
|
||||||
Event,
|
Event,
|
||||||
related_name='speakers',
|
related_name='speakers',
|
||||||
|
|
16
program/signal_handlers.py
Normal file
16
program/signal_handlers.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
def check_speaker_event_camp_consistency(sender, instance, **kwargs):
|
||||||
|
if kwargs['action'] == 'pre_add':
|
||||||
|
for pk in kwargs['pk_set']:
|
||||||
|
# check if this event belongs to a different event than the speaker does
|
||||||
|
from program.models import Event
|
||||||
|
event = Event.objects.get(id=pk)
|
||||||
|
if event.camp != instance.camp:
|
||||||
|
raise ValidationError({'events': 'One or more events belong to a different camp (%s) than the speaker (%s) does' % (event.camp, instance.camp)})
|
||||||
|
|
||||||
|
def check_speaker_camp_change(sender, instance, **kwargs):
|
||||||
|
for event in instance.events.all():
|
||||||
|
if event.camp != instance.camp:
|
||||||
|
raise ValidationError({'camp': 'You cannot change the camp a speaker belongs to if the speaker is associated with one or more events.'})
|
||||||
|
|
|
@ -15,6 +15,17 @@
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<a href="{% url 'schedule_index' camp_slug=camp.slug %}" style="background-color: black; border: 0; color: white; display: inline-block; padding: 5px;">
|
||||||
|
All
|
||||||
|
</a>
|
||||||
|
{% for event_type in camp.event_types %}
|
||||||
|
<a href="{% url 'schedule_index' camp_slug=camp.slug %}?type={{ event_type.slug }}" style="background-color: {{ event_type.color }}; border: 0; color: {% if event_type.light_text %}white{% else %}black{% endif %}; display: inline-block; padding: 5px;">
|
||||||
|
{{ event_type.name }}
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
{% block program_content %}
|
{% block program_content %}
|
||||||
{% endblock program_content %}
|
{% endblock program_content %}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,13 @@
|
||||||
{% extends 'program_base.html' %}
|
{% extends 'program_base.html' %}
|
||||||
|
|
||||||
{% block program_content %}
|
{% block program_content %}
|
||||||
<a href="{% url 'schedule_index' camp_slug=camp.slug %}" style="background-color: black; border: 0; color: white; display: inline-block; padding: 5px;">
|
|
||||||
All
|
|
||||||
</a>
|
|
||||||
{% for event_type in camp.event_types %}
|
|
||||||
<a href="{% url 'schedule_index' camp_slug=camp.slug %}?type={{ event_type.slug }}" style="background-color: {{ event_type.color }}; border: 0; color: {% if event_type.light_text %}white{% else %}black{% endif %}; display: inline-block; padding: 5px;">
|
|
||||||
{{ event_type.name }}
|
|
||||||
</a>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
{% for day in camp.camp_days %}
|
{% for day in camp.camp_days %}
|
||||||
{{ day.lower.date|date:"D d/m" }} <br />
|
{{ day.lower.date|date:"D d/m" }} <br />
|
||||||
<div style="display: flex; flex-wrap: wrap;">
|
<div style="display: flex; flex-wrap: wrap;">
|
||||||
{% for event in camp.events.all %}
|
{% for event in camp.events.all %}
|
||||||
{% for eventinstance in event.instances.all %}
|
{% for eventinstance in event.instances.all %}
|
||||||
{% if eventinstance.schedule_date == day.lower.date %}
|
{% if eventinstance.schedule_date == day.lower.date %}
|
||||||
|
{% if not eventtype or eventtype == eventinstance.event.event_type %}
|
||||||
<a class="event"
|
<a class="event"
|
||||||
href="{% url 'event_detail' camp_slug=camp.slug slug=eventinstance.event.slug %}"
|
href="{% url 'event_detail' camp_slug=camp.slug slug=eventinstance.event.slug %}"
|
||||||
style="background-color: {{ eventinstance.event.event_type.color }}; border: 0; color: {% if eveninstance.event.event_type.light_text %}white{% else %}black{% endif %};">
|
style="background-color: {{ eventinstance.event.event_type.color }}; border: 0; color: {% if eveninstance.event.event_type.light_text %}white{% else %}black{% endif %};">
|
||||||
|
@ -28,6 +18,7 @@
|
||||||
{% if event.speakers.exists %}<i>by {{ event.speakers.all|join:", " }}{% endif %}</i>
|
{% if event.speakers.exists %}<i>by {{ event.speakers.all|join:", " }}{% endif %}</i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,9 @@ class SpeakerListView(CampViewMixin, ListView):
|
||||||
model = models.Speaker
|
model = models.Speaker
|
||||||
template_name = 'speaker_list.html'
|
template_name = 'speaker_list.html'
|
||||||
|
|
||||||
|
def get_queryset(self, *args, **kwargs):
|
||||||
|
return models.Speaker.objects.filter(camp=self.camp)
|
||||||
|
|
||||||
|
|
||||||
class EventListView(CampViewMixin, ListView):
|
class EventListView(CampViewMixin, ListView):
|
||||||
model = models.Event
|
model = models.Event
|
||||||
|
@ -27,6 +30,23 @@ class ProgramOverviewView(CampViewMixin, ListView):
|
||||||
model = models.Event
|
model = models.Event
|
||||||
template_name = 'program_overview.html'
|
template_name = 'program_overview.html'
|
||||||
|
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
""" If an event type has been supplied check if it is valid """
|
||||||
|
if 'type' in self.request.GET:
|
||||||
|
try:
|
||||||
|
eventtype = models.EventType.objects.get(
|
||||||
|
slug=self.request.GET['type']
|
||||||
|
)
|
||||||
|
except models.EventType.DoesNotExist:
|
||||||
|
raise Http404
|
||||||
|
return super(ProgramOverviewView, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
context = super(ProgramOverviewView, self).get_context_data(**kwargs)
|
||||||
|
if 'type' in self.request.GET:
|
||||||
|
context['eventtype'] = models.EventType.objects.get(slug=self.request.GET['type'])
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ProgramDayView(CampViewMixin, TemplateView):
|
class ProgramDayView(CampViewMixin, TemplateView):
|
||||||
template_name = 'program_day.html'
|
template_name = 'program_day.html'
|
||||||
|
@ -34,10 +54,10 @@ class ProgramDayView(CampViewMixin, TemplateView):
|
||||||
""" If an event type has been supplied check if it is valid """
|
""" If an event type has been supplied check if it is valid """
|
||||||
if 'type' in self.request.GET:
|
if 'type' in self.request.GET:
|
||||||
try:
|
try:
|
||||||
eventtype = EventType.objects.get(
|
eventtype = models.EventType.objects.get(
|
||||||
slug=self.request.GET['type']
|
slug=self.request.GET['type']
|
||||||
)
|
)
|
||||||
except EventType.DoesNotExist:
|
except models.EventType.DoesNotExist:
|
||||||
raise Http404
|
raise Http404
|
||||||
return super(ProgramDayView, self).dispatch(*args, **kwargs)
|
return super(ProgramDayView, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -48,17 +68,14 @@ class ProgramDayView(CampViewMixin, TemplateView):
|
||||||
skip = []
|
skip = []
|
||||||
for ei in eventinstances:
|
for ei in eventinstances:
|
||||||
if ei.schedule_date != when.date():
|
if ei.schedule_date != when.date():
|
||||||
print "skipping ei %s (wrong date %s vs %s)" % (ei, ei.schedule_date, when.date())
|
|
||||||
skip.append(ei.id)
|
skip.append(ei.id)
|
||||||
else:
|
else:
|
||||||
if 'type' in self.request.GET:
|
if 'type' in self.request.GET:
|
||||||
eventtype = EventType.objects.get(
|
eventtype = models.EventType.objects.get(
|
||||||
slug=self.request.GET['type']
|
slug=self.request.GET['type']
|
||||||
)
|
)
|
||||||
if ei.event.event_type != eventtype:
|
if ei.event.event_type != eventtype:
|
||||||
print "skipping ei %s (wrong type)" % ei
|
|
||||||
skip.append(ei.id)
|
skip.append(ei.id)
|
||||||
print "skipping %s" % skip
|
|
||||||
context['eventinstances'] = eventinstances.exclude(id__in=skip).order_by('event__event_type')
|
context['eventinstances'] = eventinstances.exclude(id__in=skip).order_by('event__event_type')
|
||||||
|
|
||||||
start = when + datetime.timedelta(hours=settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS)
|
start = when + datetime.timedelta(hours=settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS)
|
||||||
|
|
Loading…
Reference in a new issue