start work on speaker and talk submissions
This commit is contained in:
parent
5f9f9bb1d4
commit
334f0477fe
|
@ -135,6 +135,16 @@ urlpatterns = [
|
|||
SpeakerListView.as_view(),
|
||||
name='speaker_index'
|
||||
),
|
||||
url(
|
||||
r'^speakers/create/$',
|
||||
SpeakerCreateView.as_view(),
|
||||
name='speaker_create'
|
||||
),
|
||||
url(
|
||||
r'^speakers/(?P<slug>[-_\w+]+)/edit/$',
|
||||
SpeakerEditView.as_view(),
|
||||
name='speaker_edit'
|
||||
),
|
||||
url(
|
||||
r'^speakers/(?P<slug>[-_\w+]+)/$',
|
||||
SpeakerDetailView.as_view(),
|
||||
|
|
23
src/program/migrations/0026_speaker_user.py
Normal file
23
src/program/migrations/0026_speaker_user.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-06 19:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('program', '0025_auto_20170306_1938'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='speaker',
|
||||
name='user',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
22
src/program/migrations/0027_auto_20170307_1701.py
Normal file
22
src/program/migrations/0027_auto_20170307_1701.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-07 16:01
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('camps', '0019_auto_20170131_1849'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('program', '0026_speaker_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='speaker',
|
||||
unique_together=set([('camp', 'user'), ('camp', 'slug'), ('camp', 'name')]),
|
||||
),
|
||||
]
|
25
src/program/migrations/0028_auto_20170307_2014.py
Normal file
25
src/program/migrations/0028_auto_20170307_2014.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-07 19:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('program', '0027_auto_20170307_1701'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='submission_status',
|
||||
field=models.CharField(choices=[('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='pending', max_length=50),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='speaker',
|
||||
name='submission_status',
|
||||
field=models.CharField(choices=[('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='pending', max_length=50),
|
||||
),
|
||||
]
|
25
src/program/migrations/0029_auto_20170307_2042.py
Normal file
25
src/program/migrations/0029_auto_20170307_2042.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2017-03-07 19:42
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('program', '0028_auto_20170307_2014'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='submission_status',
|
||||
field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='speaker',
|
||||
name='submission_status',
|
||||
field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50),
|
||||
),
|
||||
]
|
|
@ -6,6 +6,37 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from utils.models import CreatedUpdatedModel
|
||||
from django.core.exceptions import ValidationError
|
||||
from datetime import timedelta
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
|
||||
|
||||
class UserSubmittedModel(CreatedUpdatedModel):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
SUBMISSION_DRAFT = 'draft'
|
||||
SUBMISSION_PENDING = 'pending'
|
||||
SUBMISSION_APPROVED = 'approved'
|
||||
SUBMISSION_REJECTED = 'rejected'
|
||||
|
||||
SUBMISSION_STATUSES = [
|
||||
SUBMISSION_DRAFT,
|
||||
SUBMISSION_PENDING,
|
||||
SUBMISSION_APPROVED,
|
||||
SUBMISSION_REJECTED
|
||||
]
|
||||
|
||||
SUBMISSION_STATUS_CHOICES = [
|
||||
(SUBMISSION_DRAFT, 'Draft'),
|
||||
(SUBMISSION_PENDING, 'Pending approval'),
|
||||
(SUBMISSION_APPROVED, 'Approved'),
|
||||
(SUBMISSION_REJECTED, 'Rejected'),
|
||||
]
|
||||
|
||||
submission_status = models.CharField(
|
||||
max_length=50,
|
||||
choices=SUBMISSION_STATUS_CHOICES,
|
||||
default=SUBMISSION_DRAFT,
|
||||
)
|
||||
|
||||
|
||||
class EventLocation(CreatedUpdatedModel):
|
||||
|
@ -34,7 +65,7 @@ class EventType(CreatedUpdatedModel):
|
|||
return self.name
|
||||
|
||||
|
||||
class Event(CreatedUpdatedModel):
|
||||
class Event(UserSubmittedModel):
|
||||
""" Something that is on the program one or more times. """
|
||||
title = models.CharField(max_length=255)
|
||||
slug = models.SlugField(blank=True, max_length=255)
|
||||
|
@ -71,6 +102,9 @@ class Event(CreatedUpdatedModel):
|
|||
return ", ".join(self.speakers.all().values_list('name', flat=True))
|
||||
return False
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse_lazy('event_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.slug})
|
||||
|
||||
|
||||
class EventInstance(CreatedUpdatedModel):
|
||||
""" An instance of an event """
|
||||
|
@ -123,7 +157,7 @@ def get_speaker_picture_upload_path(instance, filename):
|
|||
}
|
||||
|
||||
|
||||
class Speaker(CreatedUpdatedModel):
|
||||
class Speaker(UserSubmittedModel):
|
||||
""" A Person anchoring an event. """
|
||||
name = models.CharField(max_length=150)
|
||||
biography = models.TextField()
|
||||
|
@ -136,9 +170,16 @@ class Speaker(CreatedUpdatedModel):
|
|||
blank=True,
|
||||
)
|
||||
|
||||
user = models.ForeignKey(
|
||||
'auth.User',
|
||||
on_delete=models.PROTECT,
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ['name']
|
||||
unique_together = (('camp', 'name'), ('camp', 'slug'))
|
||||
unique_together = (('camp', 'name'), ('camp', 'slug'), ('camp', 'user'))
|
||||
|
||||
def __str__(self):
|
||||
return '%s (%s)' % (self.name, self.camp)
|
||||
|
@ -148,4 +189,7 @@ class Speaker(CreatedUpdatedModel):
|
|||
self.slug = slugify(self.name)
|
||||
super(Speaker, self).save(**kwargs)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse_lazy('speaker_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.slug})
|
||||
|
||||
|
||||
|
|
14
src/program/templates/speaker_form.html
Normal file
14
src/program/templates/speaker_form.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% extends 'program_base.html' %}
|
||||
{% load bootstrap3 %}
|
||||
|
||||
{% block program_content %}
|
||||
<h3>{% if object %}Update{% else %}Create{% endif %} speaker biography</h3>
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
{% bootstrap_button "Save as draft" button_type="submit" button_class="btn-primary" %}
|
||||
{% bootstrap_button "Save and submit" button_type="submit" button_class="btn-primary" %}
|
||||
</form>
|
||||
|
||||
{% endblock program_content %}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
from collections import OrderedDict
|
||||
import datetime
|
||||
from django.views.generic import ListView, TemplateView, DetailView
|
||||
from django.views.generic.edit import CreateView, UpdateView
|
||||
from camps.mixins import CampViewMixin
|
||||
from . import models
|
||||
from django.http import Http404
|
||||
|
@ -11,6 +12,75 @@ from django.views.decorators.http import require_safe
|
|||
from django.http import Http404
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.http import HttpResponse
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
class SpeakerCreateView(LoginRequiredMixin, CampViewMixin, CreateView):
|
||||
model = models.Speaker
|
||||
fields = ['name', 'biography', 'picture_small', 'picture_large']
|
||||
template_name = 'speaker_form.html'
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
# first make sure we don't already have a speaker for this user for this camp
|
||||
try:
|
||||
speaker = models.Speaker.objects.get(user=request.user, camp=self.camp)
|
||||
except models.Speaker.DoesNotExist:
|
||||
# no speaker exists, just show the create speaker form
|
||||
return super(SpeakerCreateView, self).get(request, *args, **kwargs)
|
||||
|
||||
# speaker already exists, where do we want to redirect?
|
||||
if speaker.submission_status == models.Speaker.SUBMISSION_DRAFT:
|
||||
messages.info(request, "You already have a draft speaker profile for %s, you can modify and submit it here" % self.camp.title)
|
||||
return redirect('speaker_edit', camp_slug=self.camp.slug, slug=speaker.slug)
|
||||
elif speaker.submission_status == models.Speaker.SUBMISSION_PENDING:
|
||||
messages.info(request, "You already have a pending speaker profile for %s, you can modify and resubmit it here" % self.camp.title)
|
||||
return redirect('speaker_edit', camp_slug=self.camp.slug, slug=speaker.slug)
|
||||
elif speaker.submission_status == models.Speaker.SUBMISSION_REJECTED:
|
||||
messages.info(request, "You already have a rejected speaker profile for %s, you can modify and resubmit it here" % self.camp.title)
|
||||
return redirect('speaker_edit', camp_slug=self.camp.slug, slug=speaker.slug)
|
||||
elif speaker.submission_status == models.Speaker.SUBMISSION_APPROVED:
|
||||
messages.info(request, "You already have an accepted speaker profile for %s, please contact the organisers if you want to modify it." % self.camp.title)
|
||||
return redirect('speaker_detail', camp_slug=self.camp.slug, slug=speaker.slug)
|
||||
else:
|
||||
# unknown submission status!
|
||||
return
|
||||
|
||||
def form_valid(self, form):
|
||||
# set camp before saving
|
||||
form.instance.camp = self.camp
|
||||
form.instance.user = self.request.user
|
||||
speaker = form.save()
|
||||
return redirect(reverse('speaker_detail', kwargs={'camp_slug': speaker.camp.slug, 'slug': speaker.slug}))
|
||||
|
||||
|
||||
class SpeakerEditView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||
model = models.Speaker
|
||||
fields = ['name', 'biography', 'picture_small', 'picture_large']
|
||||
template_name = 'speaker_form.html'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# call super dispatch now because it ets self.camp which is needed below
|
||||
response = super(SpeakerEditView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
# first make sure that this speaker belongs to the logged in user
|
||||
if self.get_object().user.username != request.user.username:
|
||||
messages.error(request, "No thanks")
|
||||
return redirect(reverse('speaker_detail', kwargs={'camp_slug': self.get_object().camp.slug, 'slug': self.get_object().slug}))
|
||||
|
||||
if self.get_object().submission_status == models.Speaker.SUBMISSION_PENDING:
|
||||
messages.info(request, "Your speaker profile for %s has already been submitted. If you modify it you will have to resubmit it." % self.get_object().camp.title)
|
||||
elif self.get_object().submission_status == models.Speaker.SUBMISSION_REJECTED:
|
||||
messages.info(request, "When you are done editing you will have to resubmit your speaker profile." % self.get_object().camp.title)
|
||||
elif self.get_object().submission_status == models.Speaker.SUBMISSION_APPROVED:
|
||||
messages.error(request, "Your speaker profile for %s has already been approved. Please contact the organisers if you want to modify it." % self.get_object().camp.title)
|
||||
return redirect(reverse('speaker_detail', kwargs={'camp_slug': self.get_object().camp.slug, 'slug': self.get_object().slug}))
|
||||
|
||||
# alright, render the form
|
||||
return super(SpeakerEditView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
@method_decorator(require_safe, name='dispatch')
|
||||
class SpeakerPictureView(CampViewMixin, DetailView):
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
|
||||
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.db import models
|
||||
from django.utils.text import slugify
|
||||
|
||||
from utils.models import CreatedUpdatedModel, UUIDModel
|
||||
|
||||
from .managers import VillageQuerySet
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue