rename models and views from submission to proposal
This commit is contained in:
parent
89bec82880
commit
a51b795bce
|
@ -134,33 +134,33 @@ urlpatterns = [
|
||||||
name='schedule_index'
|
name='schedule_index'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^submissions/', include([
|
r'^proposals/', include([
|
||||||
url(
|
url(
|
||||||
r'^$',
|
r'^$',
|
||||||
SubmissionListView.as_view(),
|
ProposalListView.as_view(),
|
||||||
name='submission_list',
|
name='proposal_list',
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^speakers/', include([
|
r'^speakers/', include([
|
||||||
url(
|
url(
|
||||||
r'^create/$',
|
r'^create/$',
|
||||||
SpeakerSubmissionCreateView.as_view(),
|
SpeakerProposalCreateView.as_view(),
|
||||||
name='speakersubmission_create'
|
name='speakerproposal_create'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^(?P<pk>[a-f0-9-]+)/$',
|
r'^(?P<pk>[a-f0-9-]+)/$',
|
||||||
SpeakerSubmissionDetailView.as_view(),
|
SpeakerProposalDetailView.as_view(),
|
||||||
name='speakersubmission_detail'
|
name='speakerproposal_detail'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^(?P<pk>[a-f0-9-]+)/edit/$',
|
r'^(?P<pk>[a-f0-9-]+)/edit/$',
|
||||||
SpeakerSubmissionUpdateView.as_view(),
|
SpeakerProposalUpdateView.as_view(),
|
||||||
name='speakersubmission_update'
|
name='speakerproposal_update'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^(?P<pk>[a-f0-9-]+)/pictures/(?P<picture>[-_\w+]+)/$',
|
r'^(?P<pk>[a-f0-9-]+)/pictures/(?P<picture>[-_\w+]+)/$',
|
||||||
SpeakerSubmissionPictureView.as_view(),
|
SpeakerProposalPictureView.as_view(),
|
||||||
name='speakersubmission_picture',
|
name='speakerproposal_picture',
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
|
@ -168,18 +168,18 @@ urlpatterns = [
|
||||||
r'^events/', include([
|
r'^events/', include([
|
||||||
url(
|
url(
|
||||||
r'^create/$',
|
r'^create/$',
|
||||||
EventSubmissionCreateView.as_view(),
|
EventProposalCreateView.as_view(),
|
||||||
name='eventsubmission_create'
|
name='eventproposal_create'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^(?P<pk>[a-f0-9-]+)/$',
|
r'^(?P<pk>[a-f0-9-]+)/$',
|
||||||
EventSubmissionDetailView.as_view(),
|
EventProposalDetailView.as_view(),
|
||||||
name='eventsubmission_detail'
|
name='eventproposal_detail'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
r'^(?P<pk>[a-f0-9-]+)/edit/$',
|
r'^(?P<pk>[a-f0-9-]+)/edit/$',
|
||||||
EventSubmissionUpdateView.as_view(),
|
EventProposalUpdateView.as_view(),
|
||||||
name='eventsubmission_update'
|
name='eventproposal_update'
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
Credit Notes
|
Credit Notes
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from django.contrib import admin
|
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)
|
@admin.register(SpeakerProposal)
|
||||||
class SpeakerSubmissionAdmin(admin.ModelAdmin):
|
class SpeakerProposalAdmin(admin.ModelAdmin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EventSubmission)
|
@admin.register(EventProposal)
|
||||||
class EventSubmissionAdmin(admin.ModelAdmin):
|
class EventProposalAdmin(admin.ModelAdmin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
104
src/program/migrations/0033_auto_20170312_1857.py
Normal file
104
src/program/migrations/0033_auto_20170312_1857.py
Normal file
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,34 +2,46 @@ from django.views.generic.detail import SingleObjectMixin
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from . import models
|
from . import models
|
||||||
|
from django.contrib import messages
|
||||||
|
|
||||||
|
|
||||||
class CreateUserSubmissionMixin(SingleObjectMixin):
|
class CreateUserProposalMixin(SingleObjectMixin):
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# set camp and user before saving
|
# set camp and user before saving
|
||||||
form.instance.camp = self.camp
|
form.instance.camp = self.camp
|
||||||
form.instance.user = self.request.user
|
form.instance.user = self.request.user
|
||||||
speaker = form.save()
|
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):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
# do not permit editing if the submission is already approved
|
# do not permit editing if the proposal is already approved
|
||||||
if self.get_object().submission_status == models.UserSubmittedModel.SUBMISSION_APPROVED:
|
if self.get_object().proposal_status == models.UserSubmittedModel.PROPOSAL_APPROVED:
|
||||||
messages.error(request, "This submission has already been approved. Please contact the organisers if you need to modify something." % self.camp.title)
|
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('submissions_list', kwargs={'camp_slug': self.camp.slug}))
|
return redirect(reverse('proposal_list', kwargs={'camp_slug': self.camp.slug}))
|
||||||
|
|
||||||
# alright, continue with the request
|
# alright, continue with the request
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class EnsureUserOwnsSubmissionMixin(SingleObjectMixin):
|
class EnsureWritableCampMixin(SingleObjectMixin):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
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:
|
if self.get_object().user.username != request.user.username:
|
||||||
messages.error(request, "No thanks")
|
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
|
# alright, continue with the request
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import uuid
|
||||||
class UserSubmittedModel(CampRelatedModel):
|
class UserSubmittedModel(CampRelatedModel):
|
||||||
"""
|
"""
|
||||||
An abstract model containing the stuff that is shared
|
An abstract model containing the stuff that is shared
|
||||||
between the SpeakerSubmission and EventSubmission models.
|
between the SpeakerProposal and EventProposal models.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -29,50 +29,59 @@ class UserSubmittedModel(CampRelatedModel):
|
||||||
'auth.User',
|
'auth.User',
|
||||||
)
|
)
|
||||||
|
|
||||||
SUBMISSION_DRAFT = 'draft'
|
PROPOSAL_DRAFT = 'draft'
|
||||||
SUBMISSION_PENDING = 'pending'
|
PROPOSAL_PENDING = 'pending'
|
||||||
SUBMISSION_APPROVED = 'approved'
|
PROPOSAL_APPROVED = 'approved'
|
||||||
SUBMISSION_REJECTED = 'rejected'
|
PROPOSAL_REJECTED = 'rejected'
|
||||||
|
|
||||||
SUBMISSION_STATUSES = [
|
PROPOSAL_STATUSES = [
|
||||||
SUBMISSION_DRAFT,
|
PROPOSAL_DRAFT,
|
||||||
SUBMISSION_PENDING,
|
PROPOSAL_PENDING,
|
||||||
SUBMISSION_APPROVED,
|
PROPOSAL_APPROVED,
|
||||||
SUBMISSION_REJECTED
|
PROPOSAL_REJECTED
|
||||||
]
|
]
|
||||||
|
|
||||||
SUBMISSION_STATUS_CHOICES = [
|
PROPOSAL_STATUS_CHOICES = [
|
||||||
(SUBMISSION_DRAFT, 'Draft'),
|
(PROPOSAL_DRAFT, 'Draft'),
|
||||||
(SUBMISSION_PENDING, 'Pending approval'),
|
(PROPOSAL_PENDING, 'Pending approval'),
|
||||||
(SUBMISSION_APPROVED, 'Approved'),
|
(PROPOSAL_APPROVED, 'Approved'),
|
||||||
(SUBMISSION_REJECTED, 'Rejected'),
|
(PROPOSAL_REJECTED, 'Rejected'),
|
||||||
]
|
]
|
||||||
|
|
||||||
submission_status = models.CharField(
|
proposal_status = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=SUBMISSION_STATUS_CHOICES,
|
choices=PROPOSAL_STATUS_CHOICES,
|
||||||
default=SUBMISSION_DRAFT,
|
default=PROPOSAL_DRAFT,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
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):
|
def get_speakersubmission_picture_upload_path(instance, filename):
|
||||||
""" We want speakersubmission pictures saved as MEDIA_ROOT/public/speakersubmissions/camp-slug/submission-uuid/filename """
|
""" We want speakerproposal pictures saved as MEDIA_ROOT/public/speakerproposals/camp-slug/proposal-uuid/filename """
|
||||||
return 'public/speakersubmissions/%(campslug)s/%(submissionuuid)s/%(filename)s' % {
|
return 'public/speakerproposals/%(campslug)s/%(proposaluuid)s/%(filename)s' % {
|
||||||
'campslug': instance.camp.slug,
|
'campslug': instance.camp.slug,
|
||||||
'submissionuuidd': instance.uuid,
|
'proposaluuidd': instance.uuid,
|
||||||
'filename': filename
|
'filename': filename
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SpeakerSubmission(UserSubmittedModel):
|
|
||||||
""" A speaker submission """
|
class SpeakerProposal(UserSubmittedModel):
|
||||||
|
""" A speaker proposal """
|
||||||
|
|
||||||
camp = models.ForeignKey(
|
camp = models.ForeignKey(
|
||||||
'camps.Camp',
|
'camps.Camp',
|
||||||
related_name='speakersubmissions'
|
related_name='speakerproposals'
|
||||||
)
|
)
|
||||||
|
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
|
@ -87,14 +96,14 @@ class SpeakerSubmission(UserSubmittedModel):
|
||||||
picture_large = models.ImageField(
|
picture_large = models.ImageField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
upload_to=get_speakersubmission_picture_upload_path,
|
upload_to=get_speakerproposal_picture_upload_path,
|
||||||
help_text='A picture of the speaker'
|
help_text='A picture of the speaker'
|
||||||
)
|
)
|
||||||
|
|
||||||
picture_small = models.ImageField(
|
picture_small = models.ImageField(
|
||||||
null=True,
|
null=True,
|
||||||
blank=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'
|
help_text='A thumbnail of the speaker picture'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -103,15 +112,15 @@ class SpeakerSubmission(UserSubmittedModel):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_absolute_url(self):
|
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):
|
class EventProposal(UserSubmittedModel):
|
||||||
""" An event submission """
|
""" An event proposal """
|
||||||
|
|
||||||
camp = models.ForeignKey(
|
camp = models.ForeignKey(
|
||||||
'camps.Camp',
|
'camps.Camp',
|
||||||
related_name='eventsubmissions'
|
related_name='eventproposals'
|
||||||
)
|
)
|
||||||
|
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
|
@ -129,7 +138,7 @@ class EventSubmission(UserSubmittedModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
speakers = models.ManyToManyField(
|
speakers = models.ManyToManyField(
|
||||||
'program.SpeakerSubmission',
|
'program.SpeakerProposal',
|
||||||
blank=True,
|
blank=True,
|
||||||
help_text='Pick the speaker(s) for this event',
|
help_text='Pick the speaker(s) for this event',
|
||||||
)
|
)
|
||||||
|
@ -139,7 +148,7 @@ class EventSubmission(UserSubmittedModel):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def get_absolute_url(self):
|
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',
|
help_text='The event(s) this speaker is anchoring',
|
||||||
)
|
)
|
||||||
|
|
||||||
submission = models.OneToOneField(
|
proposal = models.OneToOneField(
|
||||||
'program.SpeakerSubmission',
|
'program.SpeakerProposal',
|
||||||
null=True,
|
null=True,
|
||||||
blank=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:
|
class Meta:
|
||||||
|
|
24
src/program/templates/eventproposal_detail.html
Normal file
24
src/program/templates/eventproposal_detail.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends 'program_base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
|
||||||
|
{% block program_content %}
|
||||||
|
|
||||||
|
<h2>{{ camp.title }} Event Proposal Details</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="list">Status: <span class="badge">{{ eventproposal.proposal_status }}</span></li>
|
||||||
|
<li class="list">ID: <span class="badge">{{ eventproposal.uuid }}</span></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">{{ eventproposal.title }}</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{{ eventproposal.abstract|commonmark }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'proposal_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% endblock program_content %}
|
|
@ -6,8 +6,7 @@
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
{% bootstrap_button "Save as draft" button_type="submit" button_class="btn-primary" %}
|
{% bootstrap_button "Save draft" button_type="submit" button_class="btn-primary" %}
|
||||||
{% bootstrap_button "Save and submit for approval" button_type="submit" button_class="btn-primary" %}
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% endblock program_content %}
|
{% endblock program_content %}
|
|
@ -1,24 +0,0 @@
|
||||||
{% extends 'program_base.html' %}
|
|
||||||
{% load commonmark %}
|
|
||||||
|
|
||||||
{% block program_content %}
|
|
||||||
|
|
||||||
<h2>{{ camp.title }} Event Proposal Details</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li class="list">Status: <span class="badge">{{ eventsubmission.submission_status }}</span></li>
|
|
||||||
<li class="list">ID: <span class="badge">{{ eventsubmission.uuid }}</span></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">{{ eventsubmission.title }}</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
{{ eventsubmission.abstract|commonmark }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="{% url 'submission_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{% endblock program_content %}
|
|
83
src/program/templates/proposal_list.html
Normal file
83
src/program/templates/proposal_list.html
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{% extends 'program_base.html' %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Proposals | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block program_content %}
|
||||||
|
|
||||||
|
<h3>Your {{ camp.title }} Speaker Proposals</h3>
|
||||||
|
{% if speakerproposal_list %}
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for speakerproposal in speakerproposal_list %}
|
||||||
|
<tr>
|
||||||
|
<td><b>{{ speakerproposal.name }}</b></td>
|
||||||
|
<td><span class="badge">{{ speakerproposal.proposal_status }}</span></td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'speakerproposal_detail' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs">Details</a>
|
||||||
|
{% if not camp.read_only %}
|
||||||
|
<a href="{% url 'speakerproposal_update' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs">Modify</a>
|
||||||
|
<a href="#" class="btn btn-danger btn-xs btn-disabled" disabled>Delete</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<h4>No speaker proposals found</h4>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not camp.read_only %}
|
||||||
|
<a href="{% url 'speakerproposal_create' camp_slug=camp.slug %}" class="btn btn-primary btn-sm">Propose New Speaker</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Your {{ camp.title }} Event Proposals</h3>
|
||||||
|
{% if eventproposal_list %}
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for eventproposal in eventproposal_list %}
|
||||||
|
<tr>
|
||||||
|
<td><b>{{ eventproposal.title }}</b></td>
|
||||||
|
<td><b>{{ eventproposal.event_type }}</b></td>
|
||||||
|
<td><span class="badge">{{ eventproposal.proposal_status }}</span></td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'eventproposal_detail' camp_slug=camp.slug pk=eventproposal.uuid %}" class="btn btn-primary btn-xs">Details</a>
|
||||||
|
{% if not camp.read_only %}
|
||||||
|
<a href="{% url 'eventproposal_update' camp_slug=camp.slug pk=eventproposal.uuid %}" class="btn btn-primary btn-xs">Modify</a>
|
||||||
|
<a href="#" class="btn btn-danger btn-xs btn-disabled" disabled>Delete</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<h4>No event proposals found</h4>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not camp.read_only %}
|
||||||
|
<a href="{% url 'eventproposal_create' camp_slug=camp.slug %}" class="btn btn-primary btn-sm">Propose New Event</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -38,7 +38,7 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<a href="{% url 'submission_list' camp_slug=camp.slug %}" class="btn btn-default">Manage My Proposals</a>
|
<a href="{% url 'proposal_list' camp_slug=camp.slug %}" class="btn btn-default">Manage My Proposals</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
{% for speaker in speaker_list %}
|
{% for speaker in speaker_list %}
|
||||||
<a href="{% url 'speaker_detail' camp_slug=camp.slug slug=speaker.slug %}" class="list-group-item">
|
<a href="{% url 'speaker_detail' camp_slug=camp.slug slug=speaker.slug %}" class="list-group-item">
|
||||||
{{ speaker.name }} ({{ speaker.events.all.count }} event{{ speaker.events.all.count|pluralize }})
|
{{ speaker.name }} ({{ speaker.events.all.count }} event{{ speaker.events.all.count|pluralize }})
|
||||||
{% if not speaker.is_public %}(unpublished, {{ speaker.submission_status }}){% endif %}
|
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
37
src/program/templates/speakerproposal_detail.html
Normal file
37
src/program/templates/speakerproposal_detail.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends 'program_base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
|
||||||
|
{% block program_content %}
|
||||||
|
|
||||||
|
<h2>{{ camp.title }} Speaker Proposal Details</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li class="list">Status: <span class="badge">{{ speakerproposal.proposal_status }}</span></li>
|
||||||
|
<li class="list">ID: <span class="badge">{{ speakerproposal.uuid }}</span></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">{{ speakerproposal.name }}</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% if speakerproposal.picture_large and speakerproposal.picture_small %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 text-container">
|
||||||
|
{{ speakerproposal.biography|commonmark }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="{% url 'speakerproposal_picture' camp_slug=camp.slug pk=speakerproposal.pk picture='large' %}" >
|
||||||
|
<img src="{% url 'speakerproposal_picture' camp_slug=camp.slug pk=speakerproposal.pk picture='thumbnail' %}" alt="{{ camp.title }} speaker picture of {{ speakerproposal.name }}">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{{ speakerproposal.biography|commonmark }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'proposal_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{% endblock program_content %}
|
|
@ -6,8 +6,7 @@
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form form %}
|
{% bootstrap_form form %}
|
||||||
{% bootstrap_button "Save as draft" button_type="submit" button_class="btn-primary" %}
|
{% bootstrap_button "Save draft" button_type="submit" button_class="btn-primary" %}
|
||||||
{% bootstrap_button "Save and submit for approval" button_type="submit" button_class="btn-primary" %}
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% endblock program_content %}
|
{% endblock program_content %}
|
|
@ -1,37 +0,0 @@
|
||||||
{% extends 'program_base.html' %}
|
|
||||||
{% load commonmark %}
|
|
||||||
|
|
||||||
{% block program_content %}
|
|
||||||
|
|
||||||
<h2>{{ camp.title }} Speaker Proposal Details</h2>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li class="list">Status: <span class="badge">{{ speakersubmission.submission_status }}</span></li>
|
|
||||||
<li class="list">ID: <span class="badge">{{ speakersubmission.uuid }}</span></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">{{ speakersubmission.name }}</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
{% if speakersubmission.picture_large and speakersubmission.picture_small %}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8 text-container">
|
|
||||||
{{ speakersubmission.biography|commonmark }}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<a href="{% url 'speakersubmission_picture' camp_slug=camp.slug pk=speakersubmission.pk picture='large' %}" >
|
|
||||||
<img src="{% url 'speakersubmission_picture' camp_slug=camp.slug pk=speakersubmission.pk picture='thumbnail' %}" alt="{{ camp.title }} speaker picture of {{ speakersubmission.name }}">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
{{ speakersubmission.biography|commonmark }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="{% url 'submission_list' camp_slug=camp.slug %}" class="btn btn-primary">Back to List</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{% endblock program_content %}
|
|
|
@ -1,71 +0,0 @@
|
||||||
{% extends 'program_base.html' %}
|
|
||||||
|
|
||||||
{% block title %}
|
|
||||||
Proposals | {{ block.super }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block program_content %}
|
|
||||||
|
|
||||||
<h3>Your {{ camp.title }} Speaker Proposals</h3>
|
|
||||||
{% if speakersubmission_list %}
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for speakersubmission in speakersubmission_list %}
|
|
||||||
<tr>
|
|
||||||
<td><b>{{ speakersubmission.name }}</b></td>
|
|
||||||
<td><span class="badge">{{ speakersubmission.submission_status }}</span></td>
|
|
||||||
<td>
|
|
||||||
<a href="{% url 'speakersubmission_detail' camp_slug=camp.slug pk=speakersubmission.uuid %}" class="btn btn-primary btn-xs">Details</a>
|
|
||||||
<a href="{% url 'speakersubmission_update' camp_slug=camp.slug pk=speakersubmission.uuid %}" class="btn btn-primary btn-xs">Modify</a>
|
|
||||||
<a href="#" class="btn btn-danger btn-xs btn-disables" disabled>Delete</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% else %}
|
|
||||||
<h3>No speaker proposals found</h3>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<a href="{% url 'speakersubmission_create' camp_slug=camp.slug %}" class="btn btn-primary">Propose New Speaker</a>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<h3>Your {{ camp.title }} Event Proposals</h3>
|
|
||||||
{% if eventsubmission_list %}
|
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Title</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for eventsubmission in eventsubmission_list %}
|
|
||||||
<tr>
|
|
||||||
<td><b>{{ eventsubmission.title }}</b></td>
|
|
||||||
<td><span class="badge">{{ eventsubmission.submission_status }}</span></td>
|
|
||||||
<td>
|
|
||||||
<a href="{% url 'eventsubmission_detail' camp_slug=camp.slug pk=eventsubmission.uuid %}" class="btn btn-primary btn-xs">Details</a>
|
|
||||||
<a href="{% url 'eventsubmission_update' camp_slug=camp.slug pk=eventsubmission.uuid %}" class="btn btn-primary btn-xs">Modify</a>
|
|
||||||
<a href="#" class="btn btn-danger btn-xs btn-disabled" disabled>Delete</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% else %}
|
|
||||||
<h3>No event proposals found</h3>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<a href="{% url 'eventsubmission_create' camp_slug=camp.slug %}" class="btn btn-primary">Propose New Event</a>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -9,50 +9,53 @@ from django.contrib import messages
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from camps.mixins import CampViewMixin
|
from camps.mixins import CampViewMixin
|
||||||
from .mixins import CreateUserSubmissionMixin, EnsureUnpprovedSubmissionMixin, EnsureUserOwnsSubmissionMixin
|
from .mixins import CreateUserProposalMixin, EnsureUnpprovedProposalMixin, EnsureUserOwnsProposalMixin, EnsureWritableCampMixin
|
||||||
from . import models
|
from . import models
|
||||||
import datetime, os
|
import datetime, os
|
||||||
|
|
||||||
|
|
||||||
############## submissions ########################################################
|
############## proposals ########################################################
|
||||||
|
|
||||||
|
|
||||||
class SubmissionListView(LoginRequiredMixin, CampViewMixin, ListView):
|
class ProposalListView(LoginRequiredMixin, CampViewMixin, ListView):
|
||||||
model = models.SpeakerSubmission
|
model = models.SpeakerProposal
|
||||||
template_name = 'submission_list.html'
|
template_name = 'proposal_list.html'
|
||||||
context_object_name = 'speakersubmission_list'
|
context_object_name = 'speakerproposal_list'
|
||||||
|
|
||||||
def get_queryset(self, **kwargs):
|
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)
|
return super().get_queryset().filter(user=self.request.user)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
# add eventsubmissions to the context
|
# add eventproposals to the context
|
||||||
context['eventsubmission_list'] = models.EventSubmission.objects.filter(camp=self.camp, user=self.request.user)
|
context['eventproposal_list'] = models.EventProposal.objects.filter(camp=self.camp, user=self.request.user)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class SpeakerSubmissionCreateView(LoginRequiredMixin, CampViewMixin, CreateUserSubmissionMixin, CreateView):
|
class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, CreateUserProposalMixin, EnsureWritableCampMixin, CreateView):
|
||||||
model = models.SpeakerSubmission
|
model = models.SpeakerProposal
|
||||||
fields = ['name', 'biography', 'picture_small', 'picture_large']
|
fields = ['name', 'biography', 'picture_small', 'picture_large']
|
||||||
template_name = 'speakersubmission_form.html'
|
template_name = 'speakerproposal_form.html'
|
||||||
|
|
||||||
|
|
||||||
class SpeakerSubmissionUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, EnsureUnpprovedSubmissionMixin, UpdateView):
|
class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnpprovedProposalMixin, EnsureWritableCampMixin, UpdateView):
|
||||||
model = models.SpeakerSubmission
|
model = models.SpeakerProposal
|
||||||
fields = ['name', 'biography', 'picture_small', 'picture_large']
|
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):
|
class SpeakerProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
|
||||||
model = models.SpeakerSubmission
|
model = models.SpeakerProposal
|
||||||
template_name = 'speakersubmission_detail.html'
|
template_name = 'speakerproposal_detail.html'
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(require_safe, name='dispatch')
|
@method_decorator(require_safe, name='dispatch')
|
||||||
class SpeakerSubmissionPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, DetailView):
|
class SpeakerProposalPictureView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
|
||||||
model = models.SpeakerSubmission
|
model = models.SpeakerProposal
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# is the speaker public, or owned by current user?
|
# 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),
|
# (this works for nginx only, other webservers use x-sendfile),
|
||||||
# TODO: what about runserver mode here?
|
# TODO: what about runserver mode here?
|
||||||
response = HttpResponse()
|
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,
|
'campslug': self.camp.slug,
|
||||||
'submissionuuid': self.get_object().uuid,
|
'proposaluuid': self.get_object().uuid,
|
||||||
'filename': os.path.basename(picture.name),
|
'filename': os.path.basename(picture.name),
|
||||||
}
|
}
|
||||||
response['Content-Type'] = ''
|
response['Content-Type'] = ''
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class EventSubmissionCreateView(LoginRequiredMixin, CampViewMixin, CreateUserSubmissionMixin, CreateView):
|
class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, CreateUserProposalMixin, EnsureWritableCampMixin, CreateView):
|
||||||
model = models.EventSubmission
|
model = models.EventProposal
|
||||||
fields = ['title', 'abstract', 'event_type', 'speakers']
|
fields = ['title', 'abstract', 'event_type', 'speakers']
|
||||||
template_name = 'eventsubmission_form.html'
|
template_name = 'eventproposal_form.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**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)
|
context['form'].fields['event_type'].queryset = models.EventType.objects.filter(public=True)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EventSubmissionUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, EnsureUnpprovedSubmissionMixin, UpdateView):
|
class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, EnsureUnpprovedProposalMixin, EnsureWritableCampMixin, UpdateView):
|
||||||
model = models.EventSubmission
|
model = models.EventProposal
|
||||||
fields = ['title', 'abstract', 'event_type', 'speakers']
|
fields = ['title', 'abstract', 'event_type', 'speakers']
|
||||||
template_name = 'eventsubmission_form.html'
|
template_name = 'eventproposal_form.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_success_url(self):
|
||||||
context = super().get_context_data(**kwargs)
|
return reverse('proposal_list', kwargs={'camp_slug': self.camp.slug})
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
class EventSubmissionDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsSubmissionMixin, DetailView):
|
class EventProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView):
|
||||||
model = models.EventSubmission
|
model = models.EventProposal
|
||||||
template_name = 'eventsubmission_detail.html'
|
template_name = 'eventproposal_detail.html'
|
||||||
|
|
||||||
|
|
||||||
################## speakers ###############################################
|
################## speakers ###############################################
|
||||||
|
|
Loading…
Reference in a new issue