add admin commands to approve speaker and event proposals
This commit is contained in:
parent
c2528129a5
commit
a715cba597
|
@ -5,12 +5,22 @@ from .models import Event, Speaker, EventType, EventInstance, EventLocation, Spe
|
||||||
|
|
||||||
@admin.register(SpeakerProposal)
|
@admin.register(SpeakerProposal)
|
||||||
class SpeakerProposalAdmin(admin.ModelAdmin):
|
class SpeakerProposalAdmin(admin.ModelAdmin):
|
||||||
pass
|
def mark_speakerproposal_as_approved(self, request, queryset):
|
||||||
|
for sp in queryset:
|
||||||
|
sp.mark_as_approved()
|
||||||
|
mark_speakerproposal_as_approved.description = 'Approve and create Speaker object(s)'
|
||||||
|
|
||||||
|
actions = ['mark_speakerproposal_as_approved']
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EventProposal)
|
@admin.register(EventProposal)
|
||||||
class EventProposalAdmin(admin.ModelAdmin):
|
class EventProposalAdmin(admin.ModelAdmin):
|
||||||
pass
|
def mark_eventproposal_as_approved(self, request, queryset):
|
||||||
|
for ep in queryset:
|
||||||
|
ep.mark_as_approved()
|
||||||
|
mark_eventproposal_as_approved.description = 'Approve and create Event object(s)'
|
||||||
|
|
||||||
|
actions = ['mark_eventproposal_as_approved']
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EventLocation)
|
@admin.register(EventLocation)
|
||||||
|
|
26
src/program/migrations/0036_auto_20170316_0004.py
Normal file
26
src/program/migrations/0036_auto_20170316_0004.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-15 23:04
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import program.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('program', '0035_auto_20170314_2325'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='speakerproposal',
|
||||||
|
name='picture_large',
|
||||||
|
field=models.ImageField(blank=True, help_text='A picture of the speaker', max_length=255, null=True, storage=program.models.CustomUrlStorage(), upload_to=program.models.get_speakerproposal_picture_upload_path),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='speakerproposal',
|
||||||
|
name='picture_small',
|
||||||
|
field=models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', max_length=255, null=True, storage=program.models.CustomUrlStorage(), upload_to=program.models.get_speakerproposal_picture_upload_path),
|
||||||
|
),
|
||||||
|
]
|
|
@ -18,7 +18,7 @@ class EnsureUnapprovedProposalMixin(SingleObjectMixin):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
# do not permit editing if the proposal is already approved
|
# do not permit editing if the proposal is already approved
|
||||||
if self.get_object().proposal_status == models.UserSubmittedModel.PROPOSAL_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)
|
messages.error(request, "This proposal has already been approved. Please contact the organisers if you need to modify something.")
|
||||||
return redirect(reverse('proposal_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
|
||||||
|
|
|
@ -7,10 +7,11 @@ from utils.models import CreatedUpdatedModel, CampRelatedModel
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from django.core.urlresolvers import reverse_lazy
|
from django.core.urlresolvers import reverse_lazy
|
||||||
import uuid
|
import uuid, os
|
||||||
from django.core.files.storage import FileSystemStorage
|
from django.core.files.storage import FileSystemStorage
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
|
|
||||||
|
|
||||||
class CustomUrlStorage(FileSystemStorage):
|
class CustomUrlStorage(FileSystemStorage):
|
||||||
|
@ -138,6 +139,7 @@ class SpeakerProposal(UserSubmittedModel):
|
||||||
upload_to=get_speakerproposal_picture_upload_path,
|
upload_to=get_speakerproposal_picture_upload_path,
|
||||||
help_text='A picture of the speaker',
|
help_text='A picture of the speaker',
|
||||||
storage=storage,
|
storage=storage,
|
||||||
|
max_length=255
|
||||||
)
|
)
|
||||||
|
|
||||||
picture_small = models.ImageField(
|
picture_small = models.ImageField(
|
||||||
|
@ -146,6 +148,7 @@ class SpeakerProposal(UserSubmittedModel):
|
||||||
upload_to=get_speakerproposal_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',
|
||||||
storage=storage,
|
storage=storage,
|
||||||
|
max_length=255
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -155,6 +158,26 @@ class SpeakerProposal(UserSubmittedModel):
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy('speakerproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
|
return reverse_lazy('speakerproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
|
||||||
|
|
||||||
|
def mark_as_approved(self):
|
||||||
|
speakermodel = apps.get_model('program', 'speaker')
|
||||||
|
speakerproposalmodel = apps.get_model('program', 'speakerproposal')
|
||||||
|
speaker = speakermodel()
|
||||||
|
speaker.camp = self.camp
|
||||||
|
speaker.name = self.name
|
||||||
|
speaker.biography = self.biography
|
||||||
|
if self.picture_small and self.picture_large:
|
||||||
|
temp = ContentFile(self.picture_small.read())
|
||||||
|
temp.name = os.path.basename(self.picture_small.name)
|
||||||
|
speaker.picture_small = temp
|
||||||
|
temp = ContentFile(self.picture_large.read())
|
||||||
|
temp.name = os.path.basename(self.picture_large.name)
|
||||||
|
speaker.picture_large = temp
|
||||||
|
speaker.proposal = self
|
||||||
|
speaker.save()
|
||||||
|
|
||||||
|
self.proposal_status = speakerproposalmodel.PROPOSAL_APPROVED
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
|
||||||
class EventProposal(UserSubmittedModel):
|
class EventProposal(UserSubmittedModel):
|
||||||
""" An event proposal """
|
""" An event proposal """
|
||||||
|
@ -191,6 +214,24 @@ class EventProposal(UserSubmittedModel):
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy('eventproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
|
return reverse_lazy('eventproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
|
||||||
|
|
||||||
|
def mark_as_approved(self):
|
||||||
|
eventmodel = apps.get_model('program', 'event')
|
||||||
|
eventproposalmodel = apps.get_model('program', 'eventproposal')
|
||||||
|
event = eventmodel()
|
||||||
|
event.camp = self.camp
|
||||||
|
event.title = self.title
|
||||||
|
event.abstract = self.abstract
|
||||||
|
event.event_type = self.event_type
|
||||||
|
event.proposal = self
|
||||||
|
event.save()
|
||||||
|
# loop through the speakerproposals linked to this eventproposal and associate any related speaker objects with this event
|
||||||
|
for sp in self.speakers.all():
|
||||||
|
if sp.speaker:
|
||||||
|
event.speaker_set.add(sp.speaker)
|
||||||
|
|
||||||
|
self.proposal_status = eventproposalmodel.PROPOSAL_APPROVED
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
|
||||||
#############################################################################################
|
#############################################################################################
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,12 @@ Proposals | {{ block.super }}
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'speakerproposal_detail' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs">Details</a>
|
<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 %}
|
{% 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>
|
{% if speakerproposal.proposal_status == "approved" %}
|
||||||
{% if speakerproposal.proposal_status == "pending" %}
|
<a href="{% url 'speakerproposal_update' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs btn-disabled" disabled>Modify</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'speakerproposal_update' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs">Modify</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if speakerproposal.proposal_status == "pending" or speakerproposal.proposal_status == "approved" %}
|
||||||
<a href="{% url 'speakerproposal_submit' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs btn-disabled" disabled>Submit</a>
|
<a href="{% url 'speakerproposal_submit' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs btn-disabled" disabled>Submit</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{% url 'speakerproposal_submit' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs">Submit</a>
|
<a href="{% url 'speakerproposal_submit' camp_slug=camp.slug pk=speakerproposal.uuid %}" class="btn btn-primary btn-xs">Submit</a>
|
||||||
|
|
Loading…
Reference in a new issue