Refactor Speaker/Talk/Presentation models into their own file, add views and templates for deleting speaker and talk, add view and template for showing a talk, improve the workflow for proposing a talk that wasn't previously defined
This commit is contained in:
parent
5f16e176f9
commit
8e7c955928
18 changed files with 251 additions and 106 deletions
|
@ -10,8 +10,6 @@ from .models.profiles import (
|
||||||
Member,
|
Member,
|
||||||
Category,
|
Category,
|
||||||
Topic,
|
Topic,
|
||||||
Speaker,
|
|
||||||
Talk,
|
|
||||||
)
|
)
|
||||||
from .models.search import Searchable
|
from .models.search import Searchable
|
||||||
from .models.events import (
|
from .models.events import (
|
||||||
|
@ -22,7 +20,12 @@ from .models.events import (
|
||||||
EventPhoto,
|
EventPhoto,
|
||||||
CommonEvent,
|
CommonEvent,
|
||||||
Attendee,
|
Attendee,
|
||||||
|
)
|
||||||
|
from .models.speakers import (
|
||||||
|
Speaker,
|
||||||
|
Talk,
|
||||||
Presentation,
|
Presentation,
|
||||||
|
SpeakerRequest,
|
||||||
)
|
)
|
||||||
|
|
||||||
admin.site.register(Language)
|
admin.site.register(Language)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.utils import timezone
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from .models.locale import Country, SPR, City
|
from .models.locale import Country, SPR, City
|
||||||
from .models.profiles import Team, UserProfile, Speaker, Talk
|
from .models.profiles import Team, UserProfile
|
||||||
from .models.events import (
|
from .models.events import (
|
||||||
Event,
|
Event,
|
||||||
EventComment,
|
EventComment,
|
||||||
|
@ -14,6 +14,10 @@ from .models.events import (
|
||||||
EventSeries,
|
EventSeries,
|
||||||
Place,
|
Place,
|
||||||
EventPhoto,
|
EventPhoto,
|
||||||
|
)
|
||||||
|
from .models.speakers import (
|
||||||
|
Speaker,
|
||||||
|
Talk,
|
||||||
Presentation,
|
Presentation,
|
||||||
SpeakerRequest,
|
SpeakerRequest,
|
||||||
)
|
)
|
||||||
|
@ -343,6 +347,9 @@ class SpeakerBioForm(forms.ModelForm):
|
||||||
model = Speaker
|
model = Speaker
|
||||||
fields = ['avatar', 'title', 'bio', 'categories']
|
fields = ['avatar', 'title', 'bio', 'categories']
|
||||||
|
|
||||||
|
class DeleteSpeakerForm(forms.Form):
|
||||||
|
confirm = forms.BooleanField(label="Yes, delete series", required=True)
|
||||||
|
|
||||||
class UserTalkForm(forms.ModelForm):
|
class UserTalkForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Talk
|
model = Talk
|
||||||
|
|
|
@ -2,4 +2,4 @@ from .profiles import *
|
||||||
from .locale import *
|
from .locale import *
|
||||||
from .search import *
|
from .search import *
|
||||||
from .events import *
|
from .events import *
|
||||||
|
from .speakers import *
|
||||||
|
|
|
@ -376,28 +376,4 @@ class EventSeries(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return u'%s by %s at %s' % (self.name, self.team.name, self.start_time)
|
return u'%s by %s at %s' % (self.name, self.team.name, self.start_time)
|
||||||
|
|
||||||
class SpeakerRequest(models.Model):
|
|
||||||
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
|
||||||
topics = models.ManyToManyField('Topic', blank=True)
|
|
||||||
|
|
||||||
class Presentation(models.Model):
|
|
||||||
DECLINED=-1
|
|
||||||
PROPOSED=0
|
|
||||||
ACCEPTED=1
|
|
||||||
|
|
||||||
STATUSES = [
|
|
||||||
(DECLINED, _("Declined")),
|
|
||||||
(PROPOSED, _("Proposed")),
|
|
||||||
(ACCEPTED, _("Accepted")),
|
|
||||||
]
|
|
||||||
event = models.ForeignKey(Event, related_name='presentations', on_delete=models.CASCADE)
|
|
||||||
talk = models.ForeignKey(Talk, related_name='presentations', on_delete=models.SET_NULL, blank=False, null=True)
|
|
||||||
status = models.SmallIntegerField(choices=STATUSES, default=PROPOSED, db_index=True)
|
|
||||||
start_time = models.DateTimeField(verbose_name=_('Start Time'), db_index=True, null=True, blank=True)
|
|
||||||
|
|
||||||
created_by = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=False)
|
|
||||||
created_time = models.DateTimeField(default=timezone.now, db_index=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '%s at %s' % (self.talk.title, self.event.name)
|
|
||||||
|
|
||||||
|
|
|
@ -86,10 +86,6 @@ class UserProfile(models.Model):
|
||||||
def moderating(self):
|
def moderating(self):
|
||||||
return [member.team for member in Member.objects.filter(user=self, role__in=(Member.ADMIN, Member.MODERATOR))]
|
return [member.team for member in Member.objects.filter(user=self, role__in=(Member.ADMIN, Member.MODERATOR))]
|
||||||
|
|
||||||
@property
|
|
||||||
def talks(self):
|
|
||||||
return Talk.objects.filter(speaker__user=self)
|
|
||||||
|
|
||||||
def can_create_event(self, team):
|
def can_create_event(self, team):
|
||||||
try:
|
try:
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
|
@ -306,62 +302,3 @@ class Topic(models.Model):
|
||||||
self.slug = slugify(self.name)
|
self.slug = slugify(self.name)
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
class Speaker(models.Model):
|
|
||||||
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
|
|
||||||
avatar = ProcessedImageField(verbose_name=_("Photo Image"),
|
|
||||||
upload_to='avatars',
|
|
||||||
processors=[ResizeToFill(128, 128)],
|
|
||||||
format='PNG',
|
|
||||||
blank=True)
|
|
||||||
title = models.CharField(max_length=256, blank=True, null=True)
|
|
||||||
bio = models.TextField(verbose_name=_('Biography'), blank=True)
|
|
||||||
|
|
||||||
categories = models.ManyToManyField('Category', blank=True)
|
|
||||||
topics = models.ManyToManyField('Topic', blank=True)
|
|
||||||
|
|
||||||
def headshot(self):
|
|
||||||
if self.avatar:
|
|
||||||
return self.avatar
|
|
||||||
else:
|
|
||||||
return self.user.avatar
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if self.title:
|
|
||||||
return self.title
|
|
||||||
return self.user.__str__()
|
|
||||||
|
|
||||||
class Talk(models.Model):
|
|
||||||
PRESENTATION=0
|
|
||||||
WORKSHOP=1
|
|
||||||
PANEL=2
|
|
||||||
ROUNDTABLE=3
|
|
||||||
QANDA=4
|
|
||||||
DEMO=5
|
|
||||||
TYPES = [
|
|
||||||
(PRESENTATION, _("Presentation")),
|
|
||||||
(WORKSHOP, _("Workshop")),
|
|
||||||
(PANEL, _("Panel")),
|
|
||||||
(ROUNDTABLE, _("Roundtable")),
|
|
||||||
(QANDA, _("Q & A")),
|
|
||||||
(DEMO, _("Demonstration")),
|
|
||||||
]
|
|
||||||
speaker = models.ForeignKey(Speaker, verbose_name=_('Speaker Bio'), on_delete=models.CASCADE)
|
|
||||||
title = models.CharField(max_length=256)
|
|
||||||
abstract = models.TextField()
|
|
||||||
talk_type = models.SmallIntegerField(_("Type"), choices=TYPES, default=PRESENTATION)
|
|
||||||
web_url = models.URLField(_("Website"), null=True, blank=True)
|
|
||||||
|
|
||||||
category = models.ForeignKey('Category', on_delete=models.SET_NULL, blank=False, null=True)
|
|
||||||
topics = models.ManyToManyField('Topic', blank=True)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def future_presentations(self):
|
|
||||||
return self.presentations.filter(status__gte=0, event__start_time__gt=timezone.now())
|
|
||||||
|
|
||||||
@property
|
|
||||||
def past_presentations(self):
|
|
||||||
return self.presentations.filter(status=1, event__start_time__lte=timezone.now())
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.title
|
|
||||||
|
|
||||||
|
|
104
events/models/speakers.py
Normal file
104
events/models/speakers.py
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from imagekit.models import ImageSpecField
|
||||||
|
from imagekit.processors import ResizeToFill
|
||||||
|
|
||||||
|
from ..utils import slugify
|
||||||
|
from .locale import *
|
||||||
|
from .profiles import *
|
||||||
|
from .events import *
|
||||||
|
from .search import *
|
||||||
|
from .. import location
|
||||||
|
|
||||||
|
import pytz
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
class Speaker(models.Model):
|
||||||
|
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
|
||||||
|
avatar = ProcessedImageField(verbose_name=_("Photo Image"),
|
||||||
|
upload_to='avatars',
|
||||||
|
processors=[ResizeToFill(128, 128)],
|
||||||
|
format='PNG',
|
||||||
|
blank=True)
|
||||||
|
title = models.CharField(max_length=256, blank=True, null=True)
|
||||||
|
bio = models.TextField(verbose_name=_('Biography'), blank=True)
|
||||||
|
|
||||||
|
categories = models.ManyToManyField('Category', blank=True)
|
||||||
|
topics = models.ManyToManyField('Topic', blank=True)
|
||||||
|
|
||||||
|
def headshot(self):
|
||||||
|
if self.avatar:
|
||||||
|
return self.avatar
|
||||||
|
else:
|
||||||
|
return self.user.avatar
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.title:
|
||||||
|
return self.title
|
||||||
|
return self.user.__str__()
|
||||||
|
|
||||||
|
class Talk(models.Model):
|
||||||
|
PRESENTATION=0
|
||||||
|
WORKSHOP=1
|
||||||
|
PANEL=2
|
||||||
|
ROUNDTABLE=3
|
||||||
|
QANDA=4
|
||||||
|
DEMO=5
|
||||||
|
TYPES = [
|
||||||
|
(PRESENTATION, _("Presentation")),
|
||||||
|
(WORKSHOP, _("Workshop")),
|
||||||
|
(PANEL, _("Panel")),
|
||||||
|
(ROUNDTABLE, _("Roundtable")),
|
||||||
|
(QANDA, _("Q & A")),
|
||||||
|
(DEMO, _("Demonstration")),
|
||||||
|
]
|
||||||
|
speaker = models.ForeignKey(Speaker, verbose_name=_('Speaker Bio'), related_name='talks', on_delete=models.CASCADE)
|
||||||
|
title = models.CharField(max_length=256)
|
||||||
|
abstract = models.TextField()
|
||||||
|
talk_type = models.SmallIntegerField(_("Type"), choices=TYPES, default=PRESENTATION)
|
||||||
|
web_url = models.URLField(_("Website"), null=True, blank=True)
|
||||||
|
|
||||||
|
category = models.ForeignKey('Category', on_delete=models.SET_NULL, blank=False, null=True)
|
||||||
|
topics = models.ManyToManyField('Topic', blank=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def future_presentations(self):
|
||||||
|
return self.presentations.filter(status__gte=0, event__start_time__gt=timezone.now())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def past_presentations(self):
|
||||||
|
return self.presentations.filter(status=1, event__start_time__lte=timezone.now())
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|
||||||
|
class SpeakerRequest(models.Model):
|
||||||
|
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
||||||
|
topics = models.ManyToManyField('Topic', blank=True)
|
||||||
|
|
||||||
|
class Presentation(models.Model):
|
||||||
|
DECLINED=-1
|
||||||
|
PROPOSED=0
|
||||||
|
ACCEPTED=1
|
||||||
|
|
||||||
|
STATUSES = [
|
||||||
|
(DECLINED, _("Declined")),
|
||||||
|
(PROPOSED, _("Proposed")),
|
||||||
|
(ACCEPTED, _("Accepted")),
|
||||||
|
]
|
||||||
|
event = models.ForeignKey(Event, related_name='presentations', on_delete=models.CASCADE)
|
||||||
|
talk = models.ForeignKey(Talk, related_name='presentations', on_delete=models.CASCADE, blank=False, null=True)
|
||||||
|
status = models.SmallIntegerField(choices=STATUSES, default=PROPOSED, db_index=True)
|
||||||
|
start_time = models.DateTimeField(verbose_name=_('Start Time'), db_index=True, null=True, blank=True)
|
||||||
|
|
||||||
|
created_by = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=False)
|
||||||
|
created_time = models.DateTimeField(default=timezone.now, db_index=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
try:
|
||||||
|
return '%s at %s' % (self.talk.title, self.event.name)
|
||||||
|
except:
|
||||||
|
return "No talk"
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
<td width="120px"><b>Presentations:</b></td>
|
<td width="120px"><b>Presentations:</b></td>
|
||||||
<td>
|
<td>
|
||||||
{% for presentation in presentation_list %}
|
{% for presentation in presentation_list %}
|
||||||
<div><a href="{% url 'show-talk' presentation.talk.id %}">{{presentation.talk.title}}</a> by <a href="{% url 'show-profile' presentation.talk.speaker.user.id %}">{{presentation.talk.speaker}}</a></div>
|
<div><a href="{% url 'show-talk' presentation.talk.id %}">{{presentation.talk.title}}</a> by <a href="{% url 'show-profile' presentation.talk.speaker.user.id %}">{{presentation.talk.speaker.user}}</a>, {{presentation.talk.speaker.title}}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<a class="btn btn-primary btn-sm" href="{% url 'propose-event-talk' event.id %}">Propose a talk</a>
|
<a class="btn btn-primary btn-sm" href="{% url 'propose-event-talk' event.id %}">Propose a talk</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
<form action="{% url "add-talk" %}" method="post">
|
<form action="{% url "add-talk" %}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
{% if event %}<input type="hidden" name="event" value="{{event.id}}" />{% endif %}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
{{talk_form}}
|
{{talk_form}}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{% extends "get_together/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Confirm deletion</h2>
|
||||||
|
{% if speaker.talks.count > 0 %}
|
||||||
|
<div class="alerts">
|
||||||
|
<div class="alert alert-danger">This speaker profile has {{ speaker.talks.count }} talks!</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
Are you sure you want to delete <strong>{{speaker.title}}</strong>?
|
||||||
|
<form action="{% url "delete-speaker" speaker.id %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="form-group">
|
||||||
|
{{ delete_form }}
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-danger">Delete Talk</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<h2>Confirm deletion</h2>
|
<h2>Confirm deletion</h2>
|
||||||
{% if talk.future_presentations.count > 0 %}
|
{% if talk.future_presentations.count > 0 %}
|
||||||
<div class="alerts">
|
<div class="alerts">
|
||||||
<div class="alert alert-danger">This talk has {{ talk.future_presentations.count }} pending event!</div>
|
<div class="alert alert-danger">This talk has {{ talk.future_presentations.count }} pending events!</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Are you sure you want to delete <strong>{{talk.title}}</strong>?
|
Are you sure you want to delete <strong>{{talk.title}}</strong>?
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
<button type="submit" class="btn btn-primary">Save</button>
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<a href="{% url 'delete-speaker' speaker.id %}" class="btn btn-danger">Delete</a>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block javascript %}
|
{% block javascript %}
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<a href="{{event.get_absolute_url}}" class="btn btn-secondary">Cancel</a>
|
<a href="{{event.get_absolute_url}}" class="btn btn-secondary">Cancel</a>
|
||||||
<a href="{% url 'add-user-talk' %}" class="btn btn-success">New Talk</a>
|
<a href="{% url 'add-talk' %}?event={{event.id}}" class="btn btn-success">New Talk</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
50
get_together/templates/get_together/speakers/show_talk.html
Normal file
50
get_together/templates/get_together/speakers/show_talk.html
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
{% extends "get_together/base.html" %}
|
||||||
|
{% load markup static %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-9">
|
||||||
|
<h2>{{ talk.title }}
|
||||||
|
{% if talk.speaker.user == request.user.profile %}
|
||||||
|
<a href="{% url 'edit-talk' talk.id %}" class="btn btn-secondary btn-sm">Edit Talk</a>
|
||||||
|
{% endif %}
|
||||||
|
</h2>
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<td><b>Speaker:</b></td><td>{{ talk.speaker }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b>Category:</b></td><td>{{ talk.category }}</td>
|
||||||
|
</tr>
|
||||||
|
{% if talk.web_url %}
|
||||||
|
<tr>
|
||||||
|
<td><b>Website:</b></td><td><a href="{{ talk.web_url }}" target="_blank">{{ talk.web_url }}</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
<tr>
|
||||||
|
<td><b>Abstract:</b></td><td>{{ talk.abstract|markdown }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><h4>Events ({{presentations.count}})</h4><hr/></div>
|
||||||
|
</div>
|
||||||
|
{% for presentation in presentations %}
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<h6 class="mt-2 mb-0"><a href="{{presentation.event.get_absolute_url}}">{{presentation.event.name}}</a></h6>
|
||||||
|
<small class="text-muted">{{ presentation.event.local_start_time }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -35,11 +35,11 @@
|
||||||
{% if user.weburl %}
|
{% if user.weburl %}
|
||||||
<p>Homepage: {{user.weburl}}</p>
|
<p>Homepage: {{user.weburl}}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.talks %}
|
{% if talks %}
|
||||||
<h3>Talks</h3>
|
<h3>Talks</h3>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% for talk in user.talks %}
|
{% for talk in talks %}
|
||||||
<div class="mr-3 mb-3 col-md-5">
|
<div class="mr-3 mb-3 col-md-5">
|
||||||
<div class="card box-shadow" >
|
<div class="card box-shadow" >
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
|
@ -14,10 +14,10 @@ from events.models.events import (
|
||||||
EventPhoto,
|
EventPhoto,
|
||||||
Place,
|
Place,
|
||||||
Attendee,
|
Attendee,
|
||||||
Presentation,
|
|
||||||
update_event_searchable,
|
update_event_searchable,
|
||||||
delete_event_searchable,
|
delete_event_searchable,
|
||||||
)
|
)
|
||||||
|
from events.models.speakers import Speaker, Talk, SpeakerRequest, Presentation
|
||||||
from events.models.profiles import Team, Organization, UserProfile, Member
|
from events.models.profiles import Team, Organization, UserProfile, Member
|
||||||
from events.forms import (
|
from events.forms import (
|
||||||
TeamEventForm,
|
TeamEventForm,
|
||||||
|
|
|
@ -6,16 +6,17 @@ from django.shortcuts import render, redirect, get_object_or_404
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
|
||||||
from events.models.profiles import UserProfile, Speaker, Talk
|
from events.models.profiles import UserProfile
|
||||||
from events.forms import (
|
from events.forms import (
|
||||||
SpeakerBioForm,
|
SpeakerBioForm,
|
||||||
|
DeleteSpeakerForm,
|
||||||
UserTalkForm,
|
UserTalkForm,
|
||||||
DeleteTalkForm,
|
DeleteTalkForm,
|
||||||
SchedulePresentationForm,
|
SchedulePresentationForm,
|
||||||
)
|
)
|
||||||
|
|
||||||
from events.models.events import Event, Presentation
|
from events.models.events import Event
|
||||||
|
from events.models.speakers import Speaker, Talk, Presentation, SpeakerRequest
|
||||||
import datetime
|
import datetime
|
||||||
import simplejson
|
import simplejson
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ def add_speaker(request):
|
||||||
speaker_form = SpeakerBioForm(request.POST, request.FILES, instance=new_speaker)
|
speaker_form = SpeakerBioForm(request.POST, request.FILES, instance=new_speaker)
|
||||||
if speaker_form.is_valid():
|
if speaker_form.is_valid():
|
||||||
new_speaker = speaker_form.save()
|
new_speaker = speaker_form.save()
|
||||||
return redirect('show-talks')
|
return redirect('user-talks')
|
||||||
else:
|
else:
|
||||||
context = {
|
context = {
|
||||||
'speaker': new_speaker,
|
'speaker': new_speaker,
|
||||||
|
@ -78,10 +79,41 @@ def edit_speaker(request, speaker_id):
|
||||||
return redirect('home')
|
return redirect('home')
|
||||||
|
|
||||||
def delete_speaker(request, speaker_id):
|
def delete_speaker(request, speaker_id):
|
||||||
pass
|
speaker = get_object_or_404(Speaker, id=speaker_id)
|
||||||
|
if not speaker.user == request.user.profile:
|
||||||
|
messages.add_message(request, messages.WARNING, message=_('You can not make changes to this speaker bio.'))
|
||||||
|
return redirect('show-speaker', speaker_id)
|
||||||
|
|
||||||
|
if request.method == 'GET':
|
||||||
|
form = DeleteSpeakerForm()
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'speaker': speaker,
|
||||||
|
'delete_form': form,
|
||||||
|
}
|
||||||
|
return render(request, 'get_together/speakers/delete_speaker.html', context)
|
||||||
|
elif request.method == 'POST':
|
||||||
|
form = DeleteSpeakerForm(request.POST)
|
||||||
|
if form.is_valid() and form.cleaned_data['confirm']:
|
||||||
|
speaker.delete()
|
||||||
|
return redirect('user-talks')
|
||||||
|
else:
|
||||||
|
context = {
|
||||||
|
'speaker': speaker,
|
||||||
|
'delete_form': form,
|
||||||
|
}
|
||||||
|
return render(request, 'get_together/speakers/delete_speaker.html', context)
|
||||||
|
else:
|
||||||
|
return redirect('home')
|
||||||
|
|
||||||
def show_talk(request, talk_id):
|
def show_talk(request, talk_id):
|
||||||
pass
|
talk = get_object_or_404(Talk, id=talk_id)
|
||||||
|
presentations = Presentation.objects.filter(talk=talk, status=Presentation.ACCEPTED).order_by('-event__start_time')
|
||||||
|
context = {
|
||||||
|
'talk': talk,
|
||||||
|
'presentations': presentations,
|
||||||
|
}
|
||||||
|
return render(request, 'get_together/speakers/show_talk.html', context)
|
||||||
|
|
||||||
def add_talk(request):
|
def add_talk(request):
|
||||||
new_talk = Talk()
|
new_talk = Talk()
|
||||||
|
@ -92,13 +124,24 @@ def add_talk(request):
|
||||||
'talk': new_talk,
|
'talk': new_talk,
|
||||||
'talk_form': talk_form,
|
'talk_form': talk_form,
|
||||||
}
|
}
|
||||||
|
if 'event' in request.GET and request.GET['event']:
|
||||||
|
context['event'] = get_object_or_404(Event, id=request.GET['event'])
|
||||||
return render(request, 'get_together/speakers/create_talk.html', context)
|
return render(request, 'get_together/speakers/create_talk.html', context)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
talk_form = UserTalkForm(request.POST, instance=new_talk)
|
talk_form = UserTalkForm(request.POST, instance=new_talk)
|
||||||
talk_form.fields['speaker'].queryset = request.user.profile.speaker_set
|
talk_form.fields['speaker'].queryset = request.user.profile.speaker_set
|
||||||
if talk_form.is_valid():
|
if talk_form.is_valid():
|
||||||
new_talk = talk_form.save()
|
new_talk = talk_form.save()
|
||||||
return redirect('user-talks')
|
if 'event' in request.POST and request.POST['event']:
|
||||||
|
event = Event.objects.get(id=request.POST['event'])
|
||||||
|
Presentation.objects.create(
|
||||||
|
event=event,
|
||||||
|
talk=new_talk,
|
||||||
|
status=Presentation.PROPOSED,
|
||||||
|
created_by=request.user.profile
|
||||||
|
)
|
||||||
|
return redirect(event.get_absolute_url())
|
||||||
|
return redirect('show-talk', new_talk.id)
|
||||||
else:
|
else:
|
||||||
context = {
|
context = {
|
||||||
'talk': new_talk,
|
'talk': new_talk,
|
||||||
|
@ -126,7 +169,7 @@ def edit_talk(request, talk_id):
|
||||||
talk_form.fields['speaker'].queryset = request.user.profile.speaker_set
|
talk_form.fields['speaker'].queryset = request.user.profile.speaker_set
|
||||||
if talk_form.is_valid():
|
if talk_form.is_valid():
|
||||||
talk = talk_form.save()
|
talk = talk_form.save()
|
||||||
return redirect('user-talks')
|
return redirect('show-talk', talk.id)
|
||||||
else:
|
else:
|
||||||
context = {
|
context = {
|
||||||
'talk': talk,
|
'talk': talk,
|
||||||
|
|
|
@ -33,10 +33,11 @@ def show_profile(request, user_id):
|
||||||
user = get_object_or_404(UserProfile, id=user_id)
|
user = get_object_or_404(UserProfile, id=user_id)
|
||||||
|
|
||||||
teams = user.memberships.all()
|
teams = user.memberships.all()
|
||||||
|
talks = Talk.objects.filter(speaker__user=user)
|
||||||
context = {
|
context = {
|
||||||
'user': user,
|
'user': user,
|
||||||
'teams': teams,
|
'teams': teams,
|
||||||
|
'talks': talks,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'get_together/users/show_profile.html', context)
|
return render(request, 'get_together/users/show_profile.html', context)
|
||||||
|
|
Loading…
Reference in a new issue