From a51b795bce01f62baf17a5c0febabc34f103407a Mon Sep 17 00:00:00 2001
From: Thomas Steen Rasmussen
Date: Sun, 12 Mar 2017 19:06:03 +0100
Subject: [PATCH] rename models and views from submission to proposal
---
src/bornhack/urls.py | 34 +++---
.../templates/profiles/profile_base.html | 1 +
src/program/admin.py | 10 +-
.../migrations/0033_auto_20170312_1857.py | 104 ++++++++++++++++++
src/program/mixins.py | 32 ++++--
src/program/models.py | 81 ++++++++------
.../templates/eventproposal_detail.html | 24 ++++
...sion_form.html => eventproposal_form.html} | 3 +-
.../templates/eventsubmission_detail.html | 24 ----
src/program/templates/proposal_list.html | 83 ++++++++++++++
src/program/templates/schedule_base.html | 2 +-
src/program/templates/speaker_list.html | 1 -
.../templates/speakerproposal_detail.html | 37 +++++++
...on_form.html => speakerproposal_form.html} | 3 +-
.../templates/speakersubmission_detail.html | 37 -------
src/program/templates/submission_list.html | 71 ------------
src/program/views.py | 74 ++++++-------
17 files changed, 378 insertions(+), 243 deletions(-)
create mode 100644 src/program/migrations/0033_auto_20170312_1857.py
create mode 100644 src/program/templates/eventproposal_detail.html
rename src/program/templates/{eventsubmission_form.html => eventproposal_form.html} (59%)
delete mode 100644 src/program/templates/eventsubmission_detail.html
create mode 100644 src/program/templates/proposal_list.html
create mode 100644 src/program/templates/speakerproposal_detail.html
rename src/program/templates/{speakersubmission_form.html => speakerproposal_form.html} (59%)
delete mode 100644 src/program/templates/speakersubmission_detail.html
delete mode 100644 src/program/templates/submission_list.html
diff --git a/src/bornhack/urls.py b/src/bornhack/urls.py
index 733849ed..71bea179 100644
--- a/src/bornhack/urls.py
+++ b/src/bornhack/urls.py
@@ -134,33 +134,33 @@ urlpatterns = [
name='schedule_index'
),
url(
- r'^submissions/', include([
+ r'^proposals/', include([
url(
r'^$',
- SubmissionListView.as_view(),
- name='submission_list',
+ ProposalListView.as_view(),
+ name='proposal_list',
),
url(
r'^speakers/', include([
url(
r'^create/$',
- SpeakerSubmissionCreateView.as_view(),
- name='speakersubmission_create'
+ SpeakerProposalCreateView.as_view(),
+ name='speakerproposal_create'
),
url(
r'^(?P[a-f0-9-]+)/$',
- SpeakerSubmissionDetailView.as_view(),
- name='speakersubmission_detail'
+ SpeakerProposalDetailView.as_view(),
+ name='speakerproposal_detail'
),
url(
r'^(?P[a-f0-9-]+)/edit/$',
- SpeakerSubmissionUpdateView.as_view(),
- name='speakersubmission_update'
+ SpeakerProposalUpdateView.as_view(),
+ name='speakerproposal_update'
),
url(
r'^(?P[a-f0-9-]+)/pictures/(?P
diff --git a/src/program/admin.py b/src/program/admin.py
index e25a5158..37f7fe51 100644
--- a/src/program/admin.py
+++ b/src/program/admin.py
@@ -1,15 +1,15 @@
from django.contrib import admin
-from .models import Event, Speaker, EventType, EventInstance, EventLocation, SpeakerSubmission, EventSubmission
+from .models import Event, Speaker, EventType, EventInstance, EventLocation, SpeakerProposal, EventProposal
-@admin.register(SpeakerSubmission)
-class SpeakerSubmissionAdmin(admin.ModelAdmin):
+@admin.register(SpeakerProposal)
+class SpeakerProposalAdmin(admin.ModelAdmin):
pass
-@admin.register(EventSubmission)
-class EventSubmissionAdmin(admin.ModelAdmin):
+@admin.register(EventProposal)
+class EventProposalAdmin(admin.ModelAdmin):
pass
diff --git a/src/program/migrations/0033_auto_20170312_1857.py b/src/program/migrations/0033_auto_20170312_1857.py
new file mode 100644
index 00000000..5f6391be
--- /dev/null
+++ b/src/program/migrations/0033_auto_20170312_1857.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-03-12 17:57
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import program.models
+import uuid
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('camps', '0020_camp_read_only'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('program', '0032_auto_20170312_1556'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='EventProposal',
+ fields=[
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ('updated', models.DateTimeField(auto_now=True)),
+ ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+ ('proposal_status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50)),
+ ('title', models.CharField(help_text='The title of this event', max_length=255)),
+ ('abstract', models.TextField(help_text='The abstract for this event')),
+ ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='eventproposals', to='camps.Camp')),
+ ('event_type', models.ForeignKey(help_text='The type of event', on_delete=django.db.models.deletion.CASCADE, to='program.EventType')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.CreateModel(
+ name='SpeakerProposal',
+ fields=[
+ ('created', models.DateTimeField(auto_now_add=True)),
+ ('updated', models.DateTimeField(auto_now=True)),
+ ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+ ('proposal_status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50)),
+ ('name', models.CharField(help_text='Name or alias of the speaker', max_length=150)),
+ ('biography', models.TextField(help_text='Markdown is supported.')),
+ ('picture_large', models.ImageField(blank=True, help_text='A picture of the speaker', null=True, upload_to=program.models.get_speakerproposal_picture_upload_path)),
+ ('picture_small', models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', null=True, upload_to=program.models.get_speakerproposal_picture_upload_path)),
+ ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='speakerproposals', to='camps.Camp')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ migrations.RemoveField(
+ model_name='eventsubmission',
+ name='camp',
+ ),
+ migrations.RemoveField(
+ model_name='eventsubmission',
+ name='event_type',
+ ),
+ migrations.RemoveField(
+ model_name='eventsubmission',
+ name='speakers',
+ ),
+ migrations.RemoveField(
+ model_name='eventsubmission',
+ name='user',
+ ),
+ migrations.RemoveField(
+ model_name='speakersubmission',
+ name='camp',
+ ),
+ migrations.RemoveField(
+ model_name='speakersubmission',
+ name='user',
+ ),
+ migrations.RemoveField(
+ model_name='speaker',
+ name='submission',
+ ),
+ migrations.DeleteModel(
+ name='EventSubmission',
+ ),
+ migrations.DeleteModel(
+ name='SpeakerSubmission',
+ ),
+ migrations.AddField(
+ model_name='eventproposal',
+ name='speakers',
+ field=models.ManyToManyField(blank=True, help_text='Pick the speaker(s) for this event', to='program.SpeakerProposal'),
+ ),
+ migrations.AddField(
+ model_name='eventproposal',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AddField(
+ model_name='speaker',
+ name='proposal',
+ field=models.OneToOneField(blank=True, help_text='The speaker proposal object this speaker was created from', null=True, on_delete=django.db.models.deletion.CASCADE, to='program.SpeakerProposal'),
+ ),
+ ]
diff --git a/src/program/mixins.py b/src/program/mixins.py
index 92c4b357..87fb9cda 100644
--- a/src/program/mixins.py
+++ b/src/program/mixins.py
@@ -2,34 +2,46 @@ from django.views.generic.detail import SingleObjectMixin
from django.shortcuts import redirect
from django.urls import reverse
from . import models
+from django.contrib import messages
-class CreateUserSubmissionMixin(SingleObjectMixin):
+class CreateUserProposalMixin(SingleObjectMixin):
def form_valid(self, form):
# set camp and user before saving
form.instance.camp = self.camp
form.instance.user = self.request.user
speaker = form.save()
- return redirect(reverse('submission_list', kwargs={'camp_slug': self.camp.slug}))
+ return redirect(reverse('proposal_list', kwargs={'camp_slug': self.camp.slug}))
-class EnsureUnpprovedSubmissionMixin(SingleObjectMixin):
+class EnsureUnpprovedProposalMixin(SingleObjectMixin):
def dispatch(self, request, *args, **kwargs):
- # do not permit editing if the submission is already approved
- if self.get_object().submission_status == models.UserSubmittedModel.SUBMISSION_APPROVED:
- messages.error(request, "This submission has already been approved. Please contact the organisers if you need to modify something." % self.camp.title)
- return redirect(reverse('submissions_list', kwargs={'camp_slug': self.camp.slug}))
+ # do not permit editing if the proposal is already approved
+ if self.get_object().proposal_status == models.UserSubmittedModel.PROPOSAL_APPROVED:
+ messages.error(request, "This proposal has already been approved. Please contact the organisers if you need to modify something." % self.camp.title)
+ return redirect(reverse('proposal_list', kwargs={'camp_slug': self.camp.slug}))
# alright, continue with the request
return super().dispatch(request, *args, **kwargs)
-class EnsureUserOwnsSubmissionMixin(SingleObjectMixin):
+class EnsureWritableCampMixin(SingleObjectMixin):
def dispatch(self, request, *args, **kwargs):
- # make sure that this submission belongs to the logged in user
+ # do not permit view if camp is in readonly mode
+ if self.camp.read_only:
+ messages.error(request, "No thanks")
+ return redirect(reverse('proposal_list', kwargs={'camp_slug': self.camp.slug}))
+
+ # alright, continue with the request
+ return super().dispatch(request, *args, **kwargs)
+
+
+class EnsureUserOwnsProposalMixin(SingleObjectMixin):
+ def dispatch(self, request, *args, **kwargs):
+ # make sure that this proposal belongs to the logged in user
if self.get_object().user.username != request.user.username:
messages.error(request, "No thanks")
- return redirect(reverse('submissions_list', kwargs={'camp_slug': self.camp.slug}))
+ return redirect(reverse('proposal_list', kwargs={'camp_slug': self.camp.slug}))
# alright, continue with the request
return super().dispatch(request, *args, **kwargs)
diff --git a/src/program/models.py b/src/program/models.py
index 289abfef..0ebe49e0 100644
--- a/src/program/models.py
+++ b/src/program/models.py
@@ -13,7 +13,7 @@ import uuid
class UserSubmittedModel(CampRelatedModel):
"""
An abstract model containing the stuff that is shared
- between the SpeakerSubmission and EventSubmission models.
+ between the SpeakerProposal and EventProposal models.
"""
class Meta:
@@ -29,50 +29,59 @@ class UserSubmittedModel(CampRelatedModel):
'auth.User',
)
- SUBMISSION_DRAFT = 'draft'
- SUBMISSION_PENDING = 'pending'
- SUBMISSION_APPROVED = 'approved'
- SUBMISSION_REJECTED = 'rejected'
+ PROPOSAL_DRAFT = 'draft'
+ PROPOSAL_PENDING = 'pending'
+ PROPOSAL_APPROVED = 'approved'
+ PROPOSAL_REJECTED = 'rejected'
- SUBMISSION_STATUSES = [
- SUBMISSION_DRAFT,
- SUBMISSION_PENDING,
- SUBMISSION_APPROVED,
- SUBMISSION_REJECTED
+ PROPOSAL_STATUSES = [
+ PROPOSAL_DRAFT,
+ PROPOSAL_PENDING,
+ PROPOSAL_APPROVED,
+ PROPOSAL_REJECTED
]
- SUBMISSION_STATUS_CHOICES = [
- (SUBMISSION_DRAFT, 'Draft'),
- (SUBMISSION_PENDING, 'Pending approval'),
- (SUBMISSION_APPROVED, 'Approved'),
- (SUBMISSION_REJECTED, 'Rejected'),
+ PROPOSAL_STATUS_CHOICES = [
+ (PROPOSAL_DRAFT, 'Draft'),
+ (PROPOSAL_PENDING, 'Pending approval'),
+ (PROPOSAL_APPROVED, 'Approved'),
+ (PROPOSAL_REJECTED, 'Rejected'),
]
- submission_status = models.CharField(
+ proposal_status = models.CharField(
max_length=50,
- choices=SUBMISSION_STATUS_CHOICES,
- default=SUBMISSION_DRAFT,
+ choices=PROPOSAL_STATUS_CHOICES,
+ default=PROPOSAL_DRAFT,
)
def __str__(self):
- return '%s (submitted by: %s, status: %s)' % (self.headline, self.user, self.submission_status)
+ return '%s (submitted by: %s, status: %s)' % (self.headline, self.user, self.proposal_status)
+def get_speakerproposal_picture_upload_path(instance, filename):
+ """ We want speakerproposal pictures saved as MEDIA_ROOT/public/speakerproposals/camp-slug/proposal-uuid/filename """
+ return 'public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
+ 'campslug': instance.camp.slug,
+ 'proposaluuidd': instance.uuid,
+ 'filename': filename
+ }
+
def get_speakersubmission_picture_upload_path(instance, filename):
- """ We want speakersubmission pictures saved as MEDIA_ROOT/public/speakersubmissions/camp-slug/submission-uuid/filename """
- return 'public/speakersubmissions/%(campslug)s/%(submissionuuid)s/%(filename)s' % {
+ """ We want speakerproposal pictures saved as MEDIA_ROOT/public/speakerproposals/camp-slug/proposal-uuid/filename """
+ return 'public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
'campslug': instance.camp.slug,
- 'submissionuuidd': instance.uuid,
+ 'proposaluuidd': instance.uuid,
'filename': filename
}
-class SpeakerSubmission(UserSubmittedModel):
- """ A speaker submission """
+
+class SpeakerProposal(UserSubmittedModel):
+ """ A speaker proposal """
camp = models.ForeignKey(
'camps.Camp',
- related_name='speakersubmissions'
+ related_name='speakerproposals'
)
name = models.CharField(
@@ -87,14 +96,14 @@ class SpeakerSubmission(UserSubmittedModel):
picture_large = models.ImageField(
null=True,
blank=True,
- upload_to=get_speakersubmission_picture_upload_path,
+ upload_to=get_speakerproposal_picture_upload_path,
help_text='A picture of the speaker'
)
picture_small = models.ImageField(
null=True,
blank=True,
- upload_to=get_speakersubmission_picture_upload_path,
+ upload_to=get_speakerproposal_picture_upload_path,
help_text='A thumbnail of the speaker picture'
)
@@ -103,15 +112,15 @@ class SpeakerSubmission(UserSubmittedModel):
return self.name
def get_absolute_url(self):
- return reverse_lazy('speakersubmission_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
+ return reverse_lazy('speakerproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
-class EventSubmission(UserSubmittedModel):
- """ An event submission """
+class EventProposal(UserSubmittedModel):
+ """ An event proposal """
camp = models.ForeignKey(
'camps.Camp',
- related_name='eventsubmissions'
+ related_name='eventproposals'
)
title = models.CharField(
@@ -129,7 +138,7 @@ class EventSubmission(UserSubmittedModel):
)
speakers = models.ManyToManyField(
- 'program.SpeakerSubmission',
+ 'program.SpeakerProposal',
blank=True,
help_text='Pick the speaker(s) for this event',
)
@@ -139,7 +148,7 @@ class EventSubmission(UserSubmittedModel):
return self.title
def get_absolute_url(self):
- return reverse_lazy('eventsubmission_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
+ return reverse_lazy('eventproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
#############################################################################################
@@ -379,11 +388,11 @@ class Speaker(CampRelatedModel):
help_text='The event(s) this speaker is anchoring',
)
- submission = models.OneToOneField(
- 'program.SpeakerSubmission',
+ proposal = models.OneToOneField(
+ 'program.SpeakerProposal',
null=True,
blank=True,
- help_text='The speaker submission object this speaker was created from',
+ help_text='The speaker proposal object this speaker was created from',
)
class Meta:
diff --git a/src/program/templates/eventproposal_detail.html b/src/program/templates/eventproposal_detail.html
new file mode 100644
index 00000000..d1988d18
--- /dev/null
+++ b/src/program/templates/eventproposal_detail.html
@@ -0,0 +1,24 @@
+{% extends 'program_base.html' %}
+{% load commonmark %}
+
+{% block program_content %}
+
+{{ camp.title }} Event Proposal Details
+
+
+ - Status: {{ eventproposal.proposal_status }}
+ - ID: {{ eventproposal.uuid }}
+
+
+
+
{{ eventproposal.title }}
+
+ {{ eventproposal.abstract|commonmark }}
+
+
+
+
+ Back to List
+
+
+{% endblock program_content %}
diff --git a/src/program/templates/eventsubmission_form.html b/src/program/templates/eventproposal_form.html
similarity index 59%
rename from src/program/templates/eventsubmission_form.html
rename to src/program/templates/eventproposal_form.html
index 7f1a8483..26a36643 100644
--- a/src/program/templates/eventsubmission_form.html
+++ b/src/program/templates/eventproposal_form.html
@@ -6,8 +6,7 @@
{% endblock program_content %}
diff --git a/src/program/templates/eventsubmission_detail.html b/src/program/templates/eventsubmission_detail.html
deleted file mode 100644
index 8dd52c5d..00000000
--- a/src/program/templates/eventsubmission_detail.html
+++ /dev/null
@@ -1,24 +0,0 @@
-{% extends 'program_base.html' %}
-{% load commonmark %}
-
-{% block program_content %}
-
-{{ camp.title }} Event Proposal Details
-
-
- - Status: {{ eventsubmission.submission_status }}
- - ID: {{ eventsubmission.uuid }}
-
-
-
-
{{ eventsubmission.title }}
-
- {{ eventsubmission.abstract|commonmark }}
-
-
-
-
- Back to List
-
-
-{% endblock program_content %}
diff --git a/src/program/templates/proposal_list.html b/src/program/templates/proposal_list.html
new file mode 100644
index 00000000..947fe6fd
--- /dev/null
+++ b/src/program/templates/proposal_list.html
@@ -0,0 +1,83 @@
+{% extends 'program_base.html' %}
+
+{% block title %}
+Proposals | {{ block.super }}
+{% endblock %}
+
+{% block program_content %}
+
+Your {{ camp.title }} Speaker Proposals
+{% if speakerproposal_list %}
+
+
+
+ Name |
+ Status |
+ Actions |
+
+
+
+ {% for speakerproposal in speakerproposal_list %}
+
+ {{ speakerproposal.name }} |
+ {{ speakerproposal.proposal_status }} |
+
+ Details
+ {% if not camp.read_only %}
+ Modify
+ Delete
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+{% else %}
+No speaker proposals found
+{% endif %}
+
+{% if not camp.read_only %}
+Propose New Speaker
+{% endif %}
+
+
+
+
+
+Your {{ camp.title }} Event Proposals
+{% if eventproposal_list %}
+
+
+
+ Title |
+ Type |
+ Status |
+ Actions |
+
+
+
+ {% for eventproposal in eventproposal_list %}
+
+ {{ eventproposal.title }} |
+ {{ eventproposal.event_type }} |
+ {{ eventproposal.proposal_status }} |
+
+ Details
+ {% if not camp.read_only %}
+ Modify
+ Delete
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+{% else %}
+No event proposals found
+{% endif %}
+
+{% if not camp.read_only %}
+ Propose New Event
+{% endif %}
+
+{% endblock %}
diff --git a/src/program/templates/schedule_base.html b/src/program/templates/schedule_base.html
index 6b54301b..18bba6d0 100644
--- a/src/program/templates/schedule_base.html
+++ b/src/program/templates/schedule_base.html
@@ -38,7 +38,7 @@
{% if request.user.is_authenticated %}
- Manage My Proposals
+ Manage My Proposals
{% endif %}
diff --git a/src/program/templates/speaker_list.html b/src/program/templates/speaker_list.html
index 6c69c0b1..80855446 100644
--- a/src/program/templates/speaker_list.html
+++ b/src/program/templates/speaker_list.html
@@ -11,7 +11,6 @@
{% for speaker in speaker_list %}
{{ speaker.name }} ({{ speaker.events.all.count }} event{{ speaker.events.all.count|pluralize }})
- {% if not speaker.is_public %}(unpublished, {{ speaker.submission_status }}){% endif %}
{% endfor %}
diff --git a/src/program/templates/speakerproposal_detail.html b/src/program/templates/speakerproposal_detail.html
new file mode 100644
index 00000000..cf1ed7fb
--- /dev/null
+++ b/src/program/templates/speakerproposal_detail.html
@@ -0,0 +1,37 @@
+{% extends 'program_base.html' %}
+{% load commonmark %}
+
+{% block program_content %}
+
+{{ camp.title }} Speaker Proposal Details
+
+
+ - Status: {{ speakerproposal.proposal_status }}
+ - ID: {{ speakerproposal.uuid }}
+
+
+
+
{{ speakerproposal.name }}
+
+ {% if speakerproposal.picture_large and speakerproposal.picture_small %}
+
+
+ {{ speakerproposal.biography|commonmark }}
+
+
+
+ {% else %}
+ {{ speakerproposal.biography|commonmark }}
+ {% endif %}
+
+
+
+
+ Back to List
+
+
+{% endblock program_content %}
diff --git a/src/program/templates/speakersubmission_form.html b/src/program/templates/speakerproposal_form.html
similarity index 59%
rename from src/program/templates/speakersubmission_form.html
rename to src/program/templates/speakerproposal_form.html
index 2b8f12ae..cfe7d6cc 100644
--- a/src/program/templates/speakersubmission_form.html
+++ b/src/program/templates/speakerproposal_form.html
@@ -6,8 +6,7 @@
{% endblock program_content %}
diff --git a/src/program/templates/speakersubmission_detail.html b/src/program/templates/speakersubmission_detail.html
deleted file mode 100644
index 52e982f4..00000000
--- a/src/program/templates/speakersubmission_detail.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends 'program_base.html' %}
-{% load commonmark %}
-
-{% block program_content %}
-
-{{ camp.title }} Speaker Proposal Details
-
-
- - Status: {{ speakersubmission.submission_status }}
- - ID: {{ speakersubmission.uuid }}
-
-
-
-
{{ speakersubmission.name }}
-
- {% if speakersubmission.picture_large and speakersubmission.picture_small %}
-
-
- {{ speakersubmission.biography|commonmark }}
-
-
-
- {% else %}
- {{ speakersubmission.biography|commonmark }}
- {% endif %}
-
-
-
-
- Back to List
-
-
-{% endblock program_content %}
diff --git a/src/program/templates/submission_list.html b/src/program/templates/submission_list.html
deleted file mode 100644
index d1821b22..00000000
--- a/src/program/templates/submission_list.html
+++ /dev/null
@@ -1,71 +0,0 @@
-{% extends 'program_base.html' %}
-
-{% block title %}
-Proposals | {{ block.super }}
-{% endblock %}
-
-{% block program_content %}
-
-Your {{ camp.title }} Speaker Proposals
-{% if speakersubmission_list %}
-
-
-
- Name |
- Status |
- Actions |
-
-
-
- {% for speakersubmission in speakersubmission_list %}
-
- {{ speakersubmission.name }} |
- {{ speakersubmission.submission_status }} |
-
- Details
- Modify
- Delete
- |
-
- {% endfor %}
-
-
-{% else %}
-No speaker proposals found
-{% endif %}
-
-Propose New Speaker
-
-
-
-
Your {{ camp.title }} Event Proposals
-{% if eventsubmission_list %}
-
-
-
- Title |
- Status |
- Actions |
-
-
-
- {% for eventsubmission in eventsubmission_list %}
-
- {{ eventsubmission.title }} |
- {{ eventsubmission.submission_status }} |
-
- Details
- Modify
- Delete
- |
-
- {% endfor %}
-
-
-{% else %}
-No event proposals found
-{% endif %}
-
-Propose New Event
-
-{% endblock %}
diff --git a/src/program/views.py b/src/program/views.py
index 0ae4b352..cd63aad7 100644
--- a/src/program/views.py
+++ b/src/program/views.py
@@ -9,50 +9,53 @@ from django.contrib import messages
from django.shortcuts import redirect
from django.urls import reverse
from camps.mixins import CampViewMixin
-from .mixins import CreateUserSubmissionMixin, EnsureUnpprovedSubmissionMixin, EnsureUserOwnsSubmissionMixin
+from .mixins import CreateUserProposalMixin, EnsureUnpprovedProposalMixin, EnsureUserOwnsProposalMixin, EnsureWritableCampMixin
from . import models
import datetime, os
-############## submissions ########################################################
+############## proposals ########################################################
-class SubmissionListView(LoginRequiredMixin, CampViewMixin, ListView):
- model = models.SpeakerSubmission
- template_name = 'submission_list.html'
- context_object_name = 'speakersubmission_list'
+class ProposalListView(LoginRequiredMixin, CampViewMixin, ListView):
+ model = models.SpeakerProposal
+ template_name = 'proposal_list.html'
+ context_object_name = 'speakerproposal_list'
def get_queryset(self, **kwargs):
- # only show speaker submissions for the current user
+ # only show speaker proposals for the current user
return super().get_queryset().filter(user=self.request.user)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- # add eventsubmissions to the context
- context['eventsubmission_list'] = models.EventSubmission.objects.filter(camp=self.camp, user=self.request.user)
+ # add eventproposals to the context
+ context['eventproposal_list'] = models.EventProposal.objects.filter(camp=self.camp, user=self.request.user)
return context
-class SpeakerSubmissionCreateView(LoginRequiredMixin, CampViewMixin, CreateUserSubmissionMixin, CreateView):
- model = models.SpeakerSubmission
+class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, CreateUserProposalMixin, EnsureWritableCampMixin, CreateView):
+ model = models.SpeakerProposal
fields = ['name', 'biography', 'picture_small', 'picture_large']
- template_name = 'speakersubmission_form.html'
+ template_name = 'speakerproposal_form.html'
-class SpeakerSubmissionUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, EnsureUnpprovedSubmissionMixin, UpdateView):
- model = models.SpeakerSubmission
+class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnpprovedProposalMixin, EnsureWritableCampMixin, UpdateView):
+ model = models.SpeakerProposal
fields = ['name', 'biography', 'picture_small', 'picture_large']
- template_name = 'speakersubmission_form.html'
+ template_name = 'speakerproposal_form.html'
+
+ def get_success_url(self):
+ return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
-class SpeakerSubmissionDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, DetailView):
- model = models.SpeakerSubmission
- template_name = 'speakersubmission_detail.html'
+class SpeakerProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
+ model = models.SpeakerProposal
+ template_name = 'speakerproposal_detail.html'
@method_decorator(require_safe, name='dispatch')
-class SpeakerSubmissionPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, DetailView):
- model = models.SpeakerSubmission
+class SpeakerProposalPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
+ model = models.SpeakerProposal
def get(self, request, *args, **kwargs):
# is the speaker public, or owned by current user?
@@ -77,42 +80,39 @@ class SpeakerSubmissionPictureView(LoginRequiredMixin, CampViewMixin, EnsureUser
# (this works for nginx only, other webservers use x-sendfile),
# TODO: what about runserver mode here?
response = HttpResponse()
- response['X-Accel-Redirect'] = '/public/speakersubmissions/%(campslug)s/%(submissionuuid)s/%(filename)s' % {
+ response['X-Accel-Redirect'] = '/public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
'campslug': self.camp.slug,
- 'submissionuuid': self.get_object().uuid,
+ 'proposaluuid': self.get_object().uuid,
'filename': os.path.basename(picture.name),
}
response['Content-Type'] = ''
return response
-class EventSubmissionCreateView(LoginRequiredMixin, CampViewMixin, CreateUserSubmissionMixin, CreateView):
- model = models.EventSubmission
+class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, CreateUserProposalMixin, EnsureWritableCampMixin, CreateView):
+ model = models.EventProposal
fields = ['title', 'abstract', 'event_type', 'speakers']
- template_name = 'eventsubmission_form.html'
+ template_name = 'eventproposal_form.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- context['form'].fields['speakers'].queryset = models.SpeakerSubmission.objects.filter(camp=self.camp, user=self.request.user)
+ context['form'].fields['speakers'].queryset = models.SpeakerProposal.objects.filter(camp=self.camp, user=self.request.user)
context['form'].fields['event_type'].queryset = models.EventType.objects.filter(public=True)
return context
-class EventSubmissionUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, EnsureUnpprovedSubmissionMixin, UpdateView):
- model = models.EventSubmission
+class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnpprovedProposalMixin, EnsureWritableCampMixin, UpdateView):
+ model = models.EventProposal
fields = ['title', 'abstract', 'event_type', 'speakers']
- template_name = 'eventsubmission_form.html'
+ template_name = 'eventproposal_form.html'
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- context['form'].fields['speakers'].queryset = models.SpeakerSubmission.objects.filter(camp=self.camp, user=self.request.user)
- context['form'].fields['event_type'].queryset = models.EventType.objects.filter(public=True)
- return context
+ def get_success_url(self):
+ return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
-class EventSubmissionDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, DetailView):
- model = models.EventSubmission
- template_name = 'eventsubmission_detail.html'
+class EventProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
+ model = models.EventProposal
+ template_name = 'eventproposal_detail.html'
################## speakers ###############################################