diff --git a/proposals/forms.py b/proposals/forms.py
index d360814..991802c 100644
--- a/proposals/forms.py
+++ b/proposals/forms.py
@@ -125,4 +125,20 @@ class TopicForm(forms.ModelForm):
return name
+class TrackForm(forms.ModelForm):
+ def __init__(self, *args, **kwargs):
+ self.site = kwargs.pop('site')
+ super().__init__(*args, **kwargs)
+
+ class Meta:
+ model = Track
+ fields = ['name', 'description']
+
+ def clean_name(self):
+ name = self.cleaned_data['name']
+ if self.instance and name != self.instance.name and Track.objects.filter(site=self.site, name=name).exists():
+ raise self.instance.unique_error_message(self._meta.model, ['name'])
+ return name
+
+
ConferenceForm = modelform_factory(Conference, fields=['cfp_opening_date', 'cfp_closing_date', 'home'])
diff --git a/proposals/templates/proposals/track_form.html b/proposals/templates/proposals/track_form.html
new file mode 100644
index 0000000..21cbdcb
--- /dev/null
+++ b/proposals/templates/proposals/track_form.html
@@ -0,0 +1,23 @@
+{% extends 'base.html' %}
+
+{% load bootstrap3 i18n %}
+
+{% block topictab %} class="active"{% endblock %}
+
+{% block css %}
+{{ block.super }}
+{{ form.media.css }}
+{% endblock %}
+
+{% block content %}
+
+
{% trans "Track" %}
+
+{% include "_form.html" %}
+
+{% endblock %}
+
+{% block js_end %}
+{{ block.super }}
+{{ form.media.js }}
+{% endblock %}
diff --git a/proposals/templates/proposals/track_list.html b/proposals/templates/proposals/track_list.html
index 8ad2423..dafbfa3 100644
--- a/proposals/templates/proposals/track_list.html
+++ b/proposals/templates/proposals/track_list.html
@@ -9,7 +9,7 @@
{% trans "Tracks" %}
{% if request|orga %}
-{% trans "Add a track (not implemented)" %}
+
{% trans "Add a track (not implemented)" %}
{% endif %}
{% cycle '' '' %}
diff --git a/proposals/urls.py b/proposals/urls.py
index 39391b2..a4686ef 100644
--- a/proposals/urls.py
+++ b/proposals/urls.py
@@ -19,6 +19,8 @@ urlpatterns = [
url(r'^topic/add/$', views.TopicCreate.as_view(), name='add-topic'),
url(r'^topic/(?P[-\w]+)/edit/$', views.TopicUpdate.as_view(), name='edit-topic'),
url(r'^track/$', views.TrackList.as_view(), name='list-tracks'),
+ url(r'^track/add/$', views.TrackCreate.as_view(), name='add-track'),
+ url(r'^track/(?P[-\w]+)/edit/$', views.TrackUpdate.as_view(), name='edit-track'),
url(r'^speakers/$', views.speaker_list, name='list-speakers'),
url(r'^speaker/(?P[\w.@+-]+)$', views.user_details, name='show-speaker'),
]
diff --git a/proposals/views.py b/proposals/views.py
index da9dcd1..79c1dcc 100644
--- a/proposals/views.py
+++ b/proposals/views.py
@@ -21,7 +21,7 @@ from accounts.utils import is_staff, is_orga
from conversations.models import ConversationWithParticipant, ConversationAboutTalk, Message
-from .forms import TalkForm, TopicForm, ConferenceForm, TalkFilterForm, STATUS_VALUES, SpeakerFilterForm
+from .forms import TalkForm, TopicForm, TrackForm, ConferenceForm, TalkFilterForm, STATUS_VALUES, SpeakerFilterForm
from .models import Talk, Track, Topic, Vote, Conference
from .signals import talk_added, talk_edited
from .utils import allowed_talks, markdown_to_html
@@ -231,6 +231,19 @@ class TopicUpdate(OrgaRequiredMixin, TopicMixin, TopicFormMixin, UpdateView):
pass
+class TrackFormMixin(object):
+ form_class = TrackForm
+
+ def get_form_kwargs(self):
+ kwargs = super().get_form_kwargs()
+ kwargs.update({'site': get_current_site(self.request)})
+ return kwargs
+
+ def form_valid(self, form):
+ form.instance.site = get_current_site(self.request)
+ return super().form_valid(form)
+
+
class TrackMixin(object):
def get_queryset(self):
return Track.objects.filter(site=get_current_site(self.request)).all()
@@ -240,6 +253,14 @@ class TrackList(LoginRequiredMixin, TrackMixin, ListView):
pass
+class TrackCreate(OrgaRequiredMixin, TrackMixin, TrackFormMixin, CreateView):
+ model = Track
+
+
+class TrackUpdate(OrgaRequiredMixin, TrackMixin, TrackFormMixin, UpdateView):
+ pass
+
+
@login_required
def vote(request, talk, score):
talk = get_object_or_404(Talk, site=get_current_site(request), slug=talk)