rework team stuff
This commit is contained in:
parent
3f9fd744ee
commit
0dc1ca9704
|
@ -288,6 +288,17 @@ urlpatterns = [
|
||||||
TeamListView.as_view(),
|
TeamListView.as_view(),
|
||||||
name='team_list'
|
name='team_list'
|
||||||
),
|
),
|
||||||
|
url(
|
||||||
|
r'(?P<slug>[-_\w+]+)/join/$',
|
||||||
|
TeamJoinView.as_view(),
|
||||||
|
name='team_join'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
r'(?P<slug>[-_\w+]+)/leave/$',
|
||||||
|
TeamLeaveView.as_view(),
|
||||||
|
name='team_leave'
|
||||||
|
),
|
||||||
|
# this has to be the last url in the list
|
||||||
url(
|
url(
|
||||||
r'(?P<slug>[-_\w+]+)/$',
|
r'(?P<slug>[-_\w+]+)/$',
|
||||||
TeamDetailView.as_view(),
|
TeamDetailView.as_view(),
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{% if speaker_list %}
|
{% if speaker_list %}
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
An alphabetical list of all speakers, workshop hosts and other
|
An alphabetical list of all speakers, workshop hosts and other
|
||||||
event anchors at BornHack 2016.
|
event anchors at {{ camp.title }}.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a href="{% url 'call_for_speakers' camp_slug=camp.slug %}" class="btn btn-primary"><span {% if not camp.call_for_speakers_open %}style="text-decoration: line-through;"{% endif %}>"Call for Speakers" for {{ camp.title }}</span></a>
|
<a href="{% url 'call_for_speakers' camp_slug=camp.slug %}" class="btn btn-primary"><span {% if not camp.call_for_speakers_open %}style="text-decoration: line-through;"{% endif %}>"Call for Speakers" for {{ camp.title }}</span></a>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import Team, TeamMember
|
from .models import Team, TeamArea, TeamMember
|
||||||
|
|
||||||
admin.site.register(Team)
|
admin.site.register(Team)
|
||||||
|
admin.site.register(TeamArea)
|
||||||
admin.site.register(TeamMember)
|
admin.site.register(TeamMember)
|
||||||
|
|
||||||
|
|
70
src/teams/migrations/0005_auto_20170402_1331.py
Normal file
70
src/teams/migrations/0005_auto_20170402_1331.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 11:31
|
||||||
|
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):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('camps', '0020_camp_read_only'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('teams', '0004_team_sub_team_of'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TeamArea',
|
||||||
|
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)),
|
||||||
|
('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')),
|
||||||
|
('responsible', models.ManyToManyField(related_name='responsible_team_areas', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['name'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='teammember',
|
||||||
|
name='team',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='teammember',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='membersnew',
|
||||||
|
field=models.ManyToManyField(related_name='teams', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='team',
|
||||||
|
name='members',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='team',
|
||||||
|
name='sub_team_of',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='area',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='teams.TeamArea'),
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='team',
|
||||||
|
unique_together=set([('name', 'camp'), ('slug', 'camp')]),
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='TeamMember',
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='teamarea',
|
||||||
|
unique_together=set([('name', 'camp')]),
|
||||||
|
),
|
||||||
|
]
|
26
src/teams/migrations/0006_auto_20170402_1331.py
Normal file
26
src/teams/migrations/0006_auto_20170402_1331.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 11:31
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('teams', '0005_auto_20170402_1331'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='team',
|
||||||
|
old_name='membersnew',
|
||||||
|
new_name='members',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='team',
|
||||||
|
name='area',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='teams.TeamArea'),
|
||||||
|
),
|
||||||
|
]
|
20
src/teams/migrations/0007_teamarea_description.py
Normal file
20
src/teams/migrations/0007_teamarea_description.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 12:15
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('teams', '0006_auto_20170402_1331'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='teamarea',
|
||||||
|
name='description',
|
||||||
|
field=models.TextField(default=''),
|
||||||
|
),
|
||||||
|
]
|
20
src/teams/migrations/0008_team_needs_members.py
Normal file
20
src/teams/migrations/0008_team_needs_members.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 13:57
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('teams', '0007_teamarea_description'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='needs_members',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
45
src/teams/migrations/0009_auto_20170402_1607.py
Normal file
45
src/teams/migrations/0009_auto_20170402_1607.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 14:07
|
||||||
|
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):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('teams', '0008_team_needs_members'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TeamMember',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('approved', models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='team',
|
||||||
|
name='members',
|
||||||
|
field=models.ManyToManyField(related_name='teamsold', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='teammember',
|
||||||
|
name='team',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teams.Team'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='teammember',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='membersnew',
|
||||||
|
field=models.ManyToManyField(related_name='teams', through='teams.TeamMember', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
]
|
19
src/teams/migrations/0010_remove_team_members.py
Normal file
19
src/teams/migrations/0010_remove_team_members.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 14:07
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('teams', '0009_auto_20170402_1607'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='team',
|
||||||
|
name='members',
|
||||||
|
),
|
||||||
|
]
|
20
src/teams/migrations/0011_auto_20170402_1608.py
Normal file
20
src/teams/migrations/0011_auto_20170402_1608.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-04-02 14:08
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('teams', '0010_remove_team_members'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='team',
|
||||||
|
old_name='membersnew',
|
||||||
|
new_name='members',
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,21 +1,35 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
|
||||||
from utils.models import CampRelatedModel
|
from utils.models import CampRelatedModel
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class TeamArea(CampRelatedModel):
|
||||||
|
class Meta:
|
||||||
|
ordering = ['name']
|
||||||
|
unique_together = ('name', 'camp')
|
||||||
|
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
description = models.TextField(default='')
|
||||||
|
camp = models.ForeignKey('camps.Camp')
|
||||||
|
responsible = models.ManyToManyField('auth.User', related_name='responsible_team_areas')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} ({})'.format(self.name, self.camp)
|
||||||
|
|
||||||
|
|
||||||
class Team(CampRelatedModel):
|
class Team(CampRelatedModel):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['name']
|
ordering = ['name']
|
||||||
unique_together = ('slug', 'camp')
|
unique_together = (('name', 'camp'), ('slug', 'camp'))
|
||||||
|
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
slug = models.SlugField(max_length=255, blank=True)
|
slug = models.SlugField(max_length=255, blank=True)
|
||||||
camp = models.ForeignKey('camps.Camp')
|
camp = models.ForeignKey('camps.Camp')
|
||||||
|
area = models.ForeignKey('teams.TeamArea', related_name='teams', on_delete=models.PROTECT)
|
||||||
description = models.TextField()
|
description = models.TextField()
|
||||||
members = models.ManyToManyField('auth.User', through='teams.TeamMember')
|
needs_members = models.BooleanField(default=True)
|
||||||
sub_team_of = models.ForeignKey('self', null=True, blank=True, related_name="sub_teams")
|
members = models.ManyToManyField('auth.User', related_name='teams', through='teams.TeamMember')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} ({})'.format(self.name, self.camp)
|
return '{} ({})'.format(self.name, self.camp)
|
||||||
|
@ -30,10 +44,25 @@ class Team(CampRelatedModel):
|
||||||
|
|
||||||
super().save(**kwargs)
|
super().save(**kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
if self.camp != self.area.camp:
|
||||||
|
raise ValidationError({'camp': 'camp is different from area.camp'})
|
||||||
|
|
||||||
|
def memberstatus(self, member):
|
||||||
|
if member not in self.members.all():
|
||||||
|
return "Not member"
|
||||||
|
else:
|
||||||
|
if TeamMember.objects.get(team=self, user=member).approved:
|
||||||
|
return "Member"
|
||||||
|
else:
|
||||||
|
return "Membership Pending"
|
||||||
|
|
||||||
|
|
||||||
class TeamMember(models.Model):
|
class TeamMember(models.Model):
|
||||||
user = models.ForeignKey('auth.User')
|
user = models.ForeignKey('auth.User')
|
||||||
team = models.ForeignKey('teams.Team')
|
team = models.ForeignKey('teams.Team')
|
||||||
responsible = models.BooleanField(default=False)
|
approved = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} ({})'.format(self.user, self.team)
|
return '{} is {} member of team {}'.format(self.user, '' if self.approved else 'an unapproved', self.team)
|
||||||
|
|
||||||
|
|
18
src/teams/templates/team_join.html
Normal file
18
src/teams/templates/team_join.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Join Team: {{ team.name }} | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h3>{{ team.name }} Team</h3>
|
||||||
|
<p class="lead">Really join the <b>{{ team.name }}</b> team? You will receive a message when your membership has been approved.<p>
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Join {{ team.name }} Team</button>
|
||||||
|
<a href="{% url 'team_list' camp_slug=camp.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
18
src/teams/templates/team_leave.html
Normal file
18
src/teams/templates/team_leave.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Join Team: {{ team.name }} | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h3>Leave {{ team.name }} Team</h3>
|
||||||
|
<p class="lead">Really leave the <b>{{ team.name }}</b> team?<p>
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form }}
|
||||||
|
<button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Leave {{ team.name }} Team</button>
|
||||||
|
<a href="{% url 'team_list' camp_slug=camp.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -13,6 +13,11 @@ Teams | {{ block.super }}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
|
<th>Area</th>
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<th>Membership</th>
|
||||||
|
<th>Action</th>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -24,28 +29,27 @@ Teams | {{ block.super }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if team.sub_teams.exists %}
|
|
||||||
<div class="pull-left">
|
|
||||||
{% endif %}
|
|
||||||
{{ team.description|unsafecommonmark|truncatewords:50 }}
|
{{ team.description|unsafecommonmark|truncatewords:50 }}
|
||||||
|
</td>
|
||||||
{% if team.sub_teams.exists %}
|
<td>
|
||||||
<div class="collapse" id="{{ team.slug }}-sub-teams">
|
{{ team.area.name }}
|
||||||
<strong>Subteams:</strong>
|
</td>
|
||||||
<ul>
|
{% if request.user.is_authenticated %}
|
||||||
{% for sub_team in team.sub_teams.all %}
|
<td>
|
||||||
<li>{{ sub_team.name }}</li>
|
{% if request.user in team.members.all %}
|
||||||
{% endfor %}
|
Member
|
||||||
</ul>
|
{% else %}
|
||||||
</div>
|
Not member
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button class="btn btn-default pull-right" type="button" data-toggle="collapse" data-target="#{{ team.slug }}-sub-teams" aria-expanded="false" aria-controls="collapseExample">
|
|
||||||
Subteams
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if request.user in team.members.all %}
|
||||||
|
<a href="{% url 'team_leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger"><i class="fa fa-minus"></i> Leave</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'team_join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success"><i class="fa fa-plus"></i> Join</button>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
from django.views.generic import ListView, DetailView
|
from django.views.generic import ListView, DetailView
|
||||||
|
from django.views.generic.edit import UpdateView
|
||||||
from camps.mixins import CampViewMixin
|
from camps.mixins import CampViewMixin
|
||||||
|
from .models import Team, TeamMember
|
||||||
from .models import Team
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.contrib import messages
|
||||||
|
|
||||||
|
|
||||||
class TeamListView(CampViewMixin, ListView):
|
class TeamListView(CampViewMixin, ListView):
|
||||||
template_name = "team_list.html"
|
template_name = "team_list.html"
|
||||||
queryset = Team.objects.filter(sub_team_of=None)
|
model = Team
|
||||||
context_object_name = 'teams'
|
context_object_name = 'teams'
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,3 +17,44 @@ class TeamDetailView(CampViewMixin, DetailView):
|
||||||
template_name = "team_detail.html"
|
template_name = "team_detail.html"
|
||||||
model = Team
|
model = Team
|
||||||
context_object_name = 'team'
|
context_object_name = 'team'
|
||||||
|
|
||||||
|
|
||||||
|
class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||||
|
template_name = "team_join.html"
|
||||||
|
model = Team
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
if request.user in self.get_object().members.all():
|
||||||
|
messages.warning(request, "You are already a member of this team")
|
||||||
|
return redirect('team_list', camp_slug=self.camp.slug)
|
||||||
|
|
||||||
|
if not self.get_object().needs_members:
|
||||||
|
messages.warning(request, "This team does not need members right now")
|
||||||
|
return redirect('team_list', camp_slug=self.get_object().camp.slug)
|
||||||
|
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
TeamMember.objects.create(team=self.get_object(), user=self.request.user)
|
||||||
|
messages.success(self.request, "You request to join the team %s has been registered, thank you." % self.get_object().name)
|
||||||
|
return redirect('team_list', camp_slug=self.get_object().camp.slug)
|
||||||
|
|
||||||
|
|
||||||
|
class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||||
|
template_name = "team_leave.html"
|
||||||
|
model = Team
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
if request.user not in self.get_object().members.all():
|
||||||
|
messages.warning(request, "You are not a member of this team")
|
||||||
|
return redirect('team_list', camp_slug=self.get_object().camp.slug)
|
||||||
|
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
TeamMember.objects.filter(team=self.get_object(), user=self.request.user).delete()
|
||||||
|
messages.success(self.request, "You are no longer a member of the team %s" % self.get_object().name)
|
||||||
|
return redirect('team_list', camp_slug=self.get_object().camp.slug)
|
||||||
|
|
||||||
|
|
|
@ -82,16 +82,16 @@
|
||||||
<div class="btn-group btn-group-justified hidden-xs">
|
<div class="btn-group btn-group-justified hidden-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>
|
||||||
<a class="btn {% menubuttonclass 'info' %}" href="{% url 'info' camp_slug=camp.slug %}">Info</a></li>
|
<a class="btn {% menubuttonclass 'info' %}" href="{% url 'info' camp_slug=camp.slug %}">Info</a></li>
|
||||||
<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 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</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>
|
||||||
<a class="btn {% menubuttonclass 'teams' %}" href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a>
|
<a class="btn {% menubuttonclass 'teams' %}" href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a>
|
||||||
</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>
|
||||||
<a class="btn {% menubuttonclass 'info' %}" href="{% url 'info' camp_slug=camp.slug %}">Info</a></li>
|
<a class="btn {% menubuttonclass 'info' %}" href="{% url 'info' camp_slug=camp.slug %}">Info</a></li>
|
||||||
<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 'villages' %}" href="{% url 'village_list' camp_slug=camp.slug %}">Villages</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>
|
||||||
<a class="btn {% menubuttonclass 'teams' %}" href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a>
|
<a class="btn {% menubuttonclass 'teams' %}" href="{% url 'team_list' camp_slug=camp.slug %}">Teams</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +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 teams.models import Team, TeamArea, 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
|
||||||
|
@ -1243,38 +1243,72 @@ 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 team areas for {}...".format(year))
|
||||||
|
pr_area = TeamArea.objects.create(
|
||||||
|
name='PR',
|
||||||
|
description="The Public Relations area covers website, social media and marketing related tasks.",
|
||||||
|
camp=camp
|
||||||
|
)
|
||||||
|
content_area = TeamArea.objects.create(
|
||||||
|
name='Content',
|
||||||
|
description="The Content area handles talks, A/V and photos.",
|
||||||
|
camp=camp
|
||||||
|
)
|
||||||
|
infrastructure_area = TeamArea.objects.create(
|
||||||
|
name='Infrastructure',
|
||||||
|
description="The Infrastructure area covers network/NOC, power, villages, CERT, logistics.",
|
||||||
|
camp=camp
|
||||||
|
)
|
||||||
|
bar_area = TeamArea.objects.create(
|
||||||
|
name='Bar',
|
||||||
|
description="The Bar area covers building and running the IRL bar, DJ booth and related tasks.",
|
||||||
|
camp=camp
|
||||||
|
)
|
||||||
|
|
||||||
|
self.output("Setting teamarea responsibles for {}...".format(year))
|
||||||
|
pr_area.responsible.add(user1, user2)
|
||||||
|
content_area.responsible.add(user2, user3)
|
||||||
|
infrastructure_area.responsible.add(user3, user4)
|
||||||
|
bar_area.responsible.add(user4)
|
||||||
|
|
||||||
self.output("Creating teams for {}...".format(year))
|
self.output("Creating teams for {}...".format(year))
|
||||||
noc_team = Team.objects.create(
|
noc_team = Team.objects.create(
|
||||||
name="NOC",
|
name="NOC",
|
||||||
description="The NOC team is in charge of establishing and running a network onsite.".format(year),
|
description="The NOC team is in charge of establishing and running a network onsite.".format(year),
|
||||||
camp=camp
|
camp=camp,
|
||||||
|
area=infrastructure_area,
|
||||||
)
|
)
|
||||||
bar_team = Team.objects.create(
|
bar_team = Team.objects.create(
|
||||||
name="Bar",
|
name="Bar",
|
||||||
description="The Bar team plans, builds and run the IRL bar!",
|
description="The Bar team plans, builds and run the IRL bar!",
|
||||||
camp=camp
|
camp=camp,
|
||||||
|
area=bar_area
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.output("Setting team members for {}...".format(year))
|
||||||
TeamMember.objects.create(
|
TeamMember.objects.create(
|
||||||
user=user2,
|
team=noc_team,
|
||||||
team=bar_team,
|
|
||||||
responsible=True
|
|
||||||
)
|
|
||||||
TeamMember.objects.create(
|
|
||||||
user=user4,
|
user=user4,
|
||||||
team=noc_team,
|
approved=True
|
||||||
responsible=True
|
|
||||||
)
|
)
|
||||||
TeamMember.objects.create(
|
TeamMember.objects.create(
|
||||||
|
team=noc_team,
|
||||||
|
user=user1
|
||||||
|
)
|
||||||
|
TeamMember.objects.create(
|
||||||
|
team=bar_team,
|
||||||
user=user1,
|
user=user1,
|
||||||
team=noc_team,
|
approved=True
|
||||||
responsible=True
|
|
||||||
)
|
)
|
||||||
TeamMember.objects.create(
|
TeamMember.objects.create(
|
||||||
|
team=bar_team,
|
||||||
user=user3,
|
user=user3,
|
||||||
team=noc_team,
|
approved=True
|
||||||
|
)
|
||||||
|
TeamMember.objects.create(
|
||||||
|
team=bar_team,
|
||||||
|
user=user2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
self.output("marking 2016 as read_only...")
|
self.output("marking 2016 as read_only...")
|
||||||
camp2016.read_only = True
|
camp2016.read_only = True
|
||||||
|
|
Loading…
Reference in a new issue