Teams (#100)
* Initial model for volunteers app. * Rename Volunteers to Teams. Add view and templates. * Adding detail page.
This commit is contained in:
parent
9d75bb6d9d
commit
5d4c4952d5
|
@ -38,6 +38,7 @@ INSTALLED_APPS = [
|
||||||
'info',
|
'info',
|
||||||
'sponsors',
|
'sponsors',
|
||||||
'ircbot',
|
'ircbot',
|
||||||
|
'teams',
|
||||||
|
|
||||||
'allauth',
|
'allauth',
|
||||||
'allauth.account',
|
'allauth.account',
|
||||||
|
@ -108,7 +109,8 @@ MIDDLEWARE = [
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
INSTALLED_APPS += ['debug_toolbar', ]
|
INSTALLED_APPS += ['debug_toolbar', ]
|
||||||
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
|
MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware'] + MIDDLEWARE
|
||||||
|
INTERNAL_IPS = "127.0.0.1"
|
||||||
|
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
'version': 1,
|
||||||
|
|
|
@ -6,6 +6,7 @@ from allauth.account.views import (
|
||||||
EmailVerificationSentView,
|
EmailVerificationSentView,
|
||||||
PasswordResetView
|
PasswordResetView
|
||||||
)
|
)
|
||||||
|
from django.conf import settings
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.views.generic import TemplateView, RedirectView
|
from django.views.generic import TemplateView, RedirectView
|
||||||
|
@ -15,6 +16,7 @@ from info.views import *
|
||||||
from villages.views import *
|
from villages.views import *
|
||||||
from program.views import *
|
from program.views import *
|
||||||
from sponsors.views import *
|
from sponsors.views import *
|
||||||
|
from teams.views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(
|
url(
|
||||||
|
@ -272,7 +274,27 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
|
|
||||||
|
url(
|
||||||
|
r'^teams/', include([
|
||||||
|
url(
|
||||||
|
r'^$',
|
||||||
|
TeamListView.as_view(),
|
||||||
|
name='team_list'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
r'(?P<slug>[-_\w+]+)/$',
|
||||||
|
TeamDetailView.as_view(),
|
||||||
|
name='team_detail'
|
||||||
|
),
|
||||||
|
])
|
||||||
|
),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
import debug_toolbar
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^__debug__/', include(debug_toolbar.urls)),
|
||||||
|
] + urlpatterns
|
||||||
|
|
0
src/teams/__init__.py
Normal file
0
src/teams/__init__.py
Normal file
6
src/teams/admin.py
Normal file
6
src/teams/admin.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from .models import Team, TeamMember
|
||||||
|
|
||||||
|
admin.site.register(Team)
|
||||||
|
admin.site.register(TeamMember)
|
5
src/teams/apps.py
Normal file
5
src/teams/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class TeamsConfig(AppConfig):
|
||||||
|
name = 'teams'
|
48
src/teams/migrations/0001_initial.py
Normal file
48
src/teams/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-27 19:09
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('camps', '0020_camp_read_only'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Team',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('created', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated', models.DateTimeField(auto_now=True)),
|
||||||
|
('name', models.CharField(max_length=255)),
|
||||||
|
('description', models.TextField()),
|
||||||
|
('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TeamMember',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('leader', models.BooleanField(default=False)),
|
||||||
|
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teams.Team')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='members',
|
||||||
|
field=models.ManyToManyField(through='teams.TeamMember', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
29
src/teams/migrations/0002_auto_20170327_2208.py
Normal file
29
src/teams/migrations/0002_auto_20170327_2208.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-27 20:08
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('camps', '0020_camp_read_only'),
|
||||||
|
('teams', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='team',
|
||||||
|
options={'ordering': ['name']},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='slug',
|
||||||
|
field=models.SlugField(blank=True, max_length=255),
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='team',
|
||||||
|
unique_together=set([('slug', 'camp')]),
|
||||||
|
),
|
||||||
|
]
|
0
src/teams/migrations/__init__.py
Normal file
0
src/teams/migrations/__init__.py
Normal file
38
src/teams/models.py
Normal file
38
src/teams/models.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.text import slugify
|
||||||
|
|
||||||
|
from utils.models import CampRelatedModel
|
||||||
|
|
||||||
|
|
||||||
|
class Team(CampRelatedModel):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['name']
|
||||||
|
unique_together = ('slug', 'camp')
|
||||||
|
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
slug = models.SlugField(max_length=255, blank=True)
|
||||||
|
camp = models.ForeignKey('camps.Camp')
|
||||||
|
description = models.TextField()
|
||||||
|
members = models.ManyToManyField('auth.User', through='teams.TeamMember')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} ({})'.format(self.name, self.camp)
|
||||||
|
|
||||||
|
def save(self, **kwargs):
|
||||||
|
if (
|
||||||
|
not self.pk or
|
||||||
|
not self.slug
|
||||||
|
):
|
||||||
|
slug = slugify(self.name)
|
||||||
|
self.slug = slug
|
||||||
|
|
||||||
|
super().save(**kwargs)
|
||||||
|
|
||||||
|
class TeamMember(models.Model):
|
||||||
|
user = models.ForeignKey('auth.User')
|
||||||
|
team = models.ForeignKey('teams.Team')
|
||||||
|
leader = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} ({})'.format(self.user, self.team)
|
14
src/teams/templates/team_detail.html
Normal file
14
src/teams/templates/team_detail.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Team: {{ team.name }} | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h3>{{ team.name }}</h3>
|
||||||
|
|
||||||
|
{{ team.description|unsafecommonmark }}
|
||||||
|
|
||||||
|
{% endblock %}
|
37
src/teams/templates/team_list.html
Normal file
37
src/teams/templates/team_list.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Teams | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% if teams %}
|
||||||
|
<table class="table table-hover table-condensed table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for team in teams %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'team_detail' camp_slug=camp.slug slug=team.slug %}">
|
||||||
|
{{ team.name }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ team.description|unsafecommonmark|truncatewords:50 }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<h4>No teams for <b>{{ camp.title }}</b> yet!</h4>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
3
src/teams/tests.py
Normal file
3
src/teams/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
17
src/teams/views.py
Normal file
17
src/teams/views.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from django.views.generic import ListView, DetailView
|
||||||
|
|
||||||
|
from camps.mixins import CampViewMixin
|
||||||
|
|
||||||
|
from .models import Team
|
||||||
|
|
||||||
|
|
||||||
|
class TeamListView(CampViewMixin, ListView):
|
||||||
|
template_name = "team_list.html"
|
||||||
|
model = Team
|
||||||
|
context_object_name = 'teams'
|
||||||
|
|
||||||
|
|
||||||
|
class TeamDetailView(CampViewMixin, DetailView):
|
||||||
|
template_name = "team_detail.html"
|
||||||
|
model = Team
|
||||||
|
context_object_name = 'team'
|
|
@ -83,6 +83,10 @@
|
||||||
<a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a>
|
<a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a>
|
||||||
<a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a>
|
<a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a>
|
||||||
<a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a>
|
<a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a>
|
||||||
|
{% if not camp.read_only %}
|
||||||
|
<a class="btn {% menubuttonclass 'teams' %}"
|
||||||
|
href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group-vertical visible-xs">
|
<div class="btn-group-vertical visible-xs">
|
||||||
<a class="btn {% menubuttonclass 'camps' %}" href="{% url 'camp_detail' camp_slug=camp.slug %}">{{ camp.title }}</a>
|
<a class="btn {% menubuttonclass 'camps' %}" href="{% url 'camp_detail' camp_slug=camp.slug %}">{{ camp.title }}</a>
|
||||||
|
@ -90,6 +94,10 @@
|
||||||
<a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a>
|
<a class="btn {% menubuttonclass 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</a>
|
||||||
<a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a>
|
<a class="btn {% menubuttonclass 'program' %}" href="{% url 'schedule_index' camp_slug=camp.slug %}">Program</a>
|
||||||
<a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a>
|
<a class="btn {% menubuttonclass 'sponsors' %}" href="{% url 'sponsors' camp_slug=camp.slug %}">Sponsors</a>
|
||||||
|
{% if not camp.read_only %}
|
||||||
|
<a class="btn {% menubuttonclass 'teams' %}"
|
||||||
|
href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,6 +7,7 @@ from shop.models import ProductCategory, Product
|
||||||
from info.models import InfoCategory, InfoItem
|
from info.models import InfoCategory, InfoItem
|
||||||
from villages.models import Village
|
from villages.models import Village
|
||||||
from program.models import EventType, Event, EventInstance, Speaker, EventLocation
|
from program.models import EventType, Event, EventInstance, Speaker, EventLocation
|
||||||
|
from teams.models import Team, TeamMember
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from allauth.account.models import EmailAddress
|
from allauth.account.models import EmailAddress
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
@ -1242,6 +1243,39 @@ Please note that sleeping in the parking lot is not permitted. If you want to sl
|
||||||
description='This village is representing TheCamp.dk, an annual danish tech camp held in July. The official subjects for this event is open source software, network and security. In reality we are interested in anything from computers to illumination soap bubbles and irish coffee'
|
description='This village is representing TheCamp.dk, an annual danish tech camp held in July. The official subjects for this event is open source software, network and security. In reality we are interested in anything from computers to illumination soap bubbles and irish coffee'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.output("Creating teams for {}...".format(year))
|
||||||
|
noc_team = Team.objects.create(
|
||||||
|
name="NOC",
|
||||||
|
description="The NOC team is in charge of establishing and running a network onsite.".format(year),
|
||||||
|
camp=camp
|
||||||
|
)
|
||||||
|
bar_team = Team.objects.create(
|
||||||
|
name="Bar",
|
||||||
|
description="The Bar team plans, builds and run the IRL bar!",
|
||||||
|
camp=camp
|
||||||
|
)
|
||||||
|
|
||||||
|
TeamMember.objects.create(
|
||||||
|
user=user2,
|
||||||
|
team=bar_team,
|
||||||
|
leader=True
|
||||||
|
)
|
||||||
|
TeamMember.objects.create(
|
||||||
|
user=user4,
|
||||||
|
team=noc_team,
|
||||||
|
leader=True
|
||||||
|
)
|
||||||
|
TeamMember.objects.create(
|
||||||
|
user=user1,
|
||||||
|
team=noc_team,
|
||||||
|
leader=True
|
||||||
|
)
|
||||||
|
TeamMember.objects.create(
|
||||||
|
user=user3,
|
||||||
|
team=noc_team,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
self.output("marking 2016 as read_only...")
|
self.output("marking 2016 as read_only...")
|
||||||
camp2016.read_only = True
|
camp2016.read_only = True
|
||||||
camp2016.save()
|
camp2016.save()
|
||||||
|
|
2
src/vendor/coinify
vendored
2
src/vendor/coinify
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit d2582a98a3c7522505e07559fc5bd58c07b6ae86
|
Subproject commit abc76101756a95e59abc8dd13e50a45d26855ccb
|
Loading…
Reference in a new issue