Add a Team slug for human readable URLs. Fixes #73
This commit is contained in:
parent
488d1f5c1e
commit
7540b93d0a
15 changed files with 84 additions and 27 deletions
34
events/migrations/0032_add_team_slug.py
Normal file
34
events/migrations/0032_add_team_slug.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Generated by Django 2.0 on 2018-06-09 01:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
from events.utils import slugify
|
||||
|
||||
|
||||
def add_team_slug(apps, schema_editor):
|
||||
Team = apps.get_model('events', 'Team')
|
||||
for team in Team.objects.all():
|
||||
team.slug = slugify(team.name)
|
||||
team.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('events', '0031_add_sponsors'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='team',
|
||||
name='slug',
|
||||
field=models.CharField(max_length=256, null=True),
|
||||
),
|
||||
migrations.RunPython(add_team_slug, reverse_code=migrations.RunPython.noop),
|
||||
migrations.AlterField(
|
||||
model_name='team',
|
||||
name='slug',
|
||||
field=models.CharField(default='', max_length=256),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -222,6 +222,7 @@ class SponsorSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Team(models.Model):
|
||||
name = models.CharField(_("Team Name"), max_length=256, null=False, blank=False)
|
||||
slug = models.CharField(max_length=256, null=False, blank=False, unique=True)
|
||||
organization = models.ForeignKey(Organization, related_name='teams', null=True, blank=True, on_delete=models.CASCADE)
|
||||
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
@ -282,6 +283,12 @@ class Team(models.Model):
|
|||
if self.city is not None:
|
||||
self.spr = self.city.spr
|
||||
self.country = self.spr.country
|
||||
new_slug = slugify(self.name)
|
||||
slug_matches = list(Team.objects.filter(slug=new_slug))
|
||||
if len(slug_matches) == 0 or (len(slug_matches) == 1 and slug_matches[0].id == self.id):
|
||||
self.slug = new_slug
|
||||
else:
|
||||
self.slug = '%s-%s' % (new_slug, self.id)
|
||||
super().save(*args, **kwargs) # Call the "real" save() method.
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
<a href="{% url 'show-team' team.id %}">
|
||||
<a href="{% url 'show-team-by-slug' team.slug %}">
|
||||
{% if team.category %}
|
||||
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
|
||||
{% else %}
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
<div class="col-md-9">
|
||||
<h2>{{ event.name }}
|
||||
</h2>
|
||||
<p class="text-muted">Hosted by <a href="{% url "show-team" team.id %}">{{ team.name }}</a></p>
|
||||
<p class="text-muted">Hosted by <a href="{% url "show-team-by-slug" team.slug %}">{{ team.name }}</a></p>
|
||||
{% if settings.SOCIAL_AUTH_TWITTER_KEY %}
|
||||
<a href="https://twitter.com/intent/tweet?text=I'm+having+a+get+together!%0D{{event.name|urlencode}}&original_referer={{event.get_full_url|urlencode}}&url={{event.get_full_url|urlencode}}&hashtags=gettogether" data-size="large" class="btn btn-twitter btn-sm"><i class="fa fa-twitter"></i> Tweet</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<a href="{% url 'edit-series' series.id %}" class="btn btn-secondary btn-sm">Edit Series</a>
|
||||
{% endif %}
|
||||
</h2>
|
||||
<p class="text-muted">Hosted by <a href="{% url "show-team" team.id %}">{{ team.name }}</a></p>
|
||||
<p class="text-muted">Hosted by <a href="{% url "show-team-by-slug" team.slug %}">{{ team.name }}</a></p>
|
||||
<hr/>
|
||||
|
||||
<p>{{ series.summary|markdown }}</p>
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
<a href="{% url 'show-team' team.id %}">
|
||||
<a href="{% url 'show-team-by-slug' team.slug %}">
|
||||
{% if team.category %}
|
||||
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
|
||||
{% else %}
|
||||
|
@ -78,11 +78,11 @@
|
|||
<p class="card-title">{{team.name}}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text"><strong><a class="card-link" href="{% url 'show-team' team.id %}">{{team.city}}</a></strong></p>
|
||||
<p class="card-text"><strong><a class="card-link" href="{% url 'show-team-by-slug' team.slug %}">{{team.city}}</a></strong></p>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<small class="text-muted">{{ team.members.count }} members</small>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-primary" href="{% url 'show-team' team.id %}">View</a></span>
|
||||
<a class="btn btn-primary" href="{% url 'show-team-by-slug' team.slug %}">View</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
<a href="{% url 'show-team' team.id %}">
|
||||
<a href="{% url 'show-team-by-slug' team.slug %}">
|
||||
{% if team.category %}
|
||||
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
|
||||
{% else %}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<div class="row mb-3">
|
||||
<div class="col media gt-profile">
|
||||
<div class="media-body">
|
||||
<h6 class="mt-0 mb-0"><a href="{% url 'show-team' member.id %}" title="{{member.name}}">{{member.name}}</a></h6>
|
||||
<h6 class="mt-0 mb-0"><a href="{% url 'show-team-by-slug' member.slug %}" title="{{member.name}}">{{member.name}}</a></h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="fluid-container">
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<h2>Invite people to <a href="{% url 'show-team' team.id %}">{{ team.name }}</a>
|
||||
<h2>Invite people to <a href="{% url 'show-team-by-slug' team.slug %}">{{ team.name }}</a>
|
||||
</h2>
|
||||
<p>Add a list of emails, separated by commas</p>
|
||||
<form action="{% url 'invite-members' team.id %}" method="POST">
|
||||
|
|
|
@ -20,19 +20,21 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
<a href="{% url 'show-team-by-slug' team.slug %}">
|
||||
{% if team.category %}
|
||||
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
|
||||
{% else %}
|
||||
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{team.name}}">
|
||||
{% endif %}
|
||||
</a>
|
||||
<p class="card-title">{{team.name}}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text"><strong><a class="card-link" href="{% url 'show-team' team.id %}">{{team.city}}</a></strong></p>
|
||||
<p class="card-text"><strong>{{team.city}}</strong></p>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<small class="text-muted">{{ team.members.count }} members</small>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-primary" href="{% url 'show-team' team.id %}">View</a></span>
|
||||
<a class="btn btn-primary" href="{% url 'show-team-by-slug' team.slug %}">View</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<div class="fluid-container">
|
||||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<h2>Members of <a href="{% url 'show-team' team.id %}">{{ team.name }}</a>
|
||||
<h2>Members of <a href="{% url 'show-team-by-slug' team.slug %}">{{ team.name }}</a>
|
||||
</h2>
|
||||
<p><a href="{% url 'invite-members' team.id %}" class="btn btn-secondary btn-sm"><i class="fa fa-user-plus"></i> Invite Members</a></p>
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<ul>
|
||||
{% for t in teams %}
|
||||
<li>
|
||||
<a href="{% url 'show-team' t.id %}" title="Team page for {{t.name}}">{{t.name}}</a>
|
||||
<a href="{% url 'show-team-by-slug' t.slug %}" title="Team page for {{t.name}}">{{t.name}}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
|
@ -64,7 +64,7 @@ urlpatterns = [
|
|||
path('events/all/', views.events_list_all, name='all-events'),
|
||||
path('teams/', views.teams_list, name='teams'),
|
||||
path('teams/all/', views.teams_list_all, name='all-teams'),
|
||||
path('team/<int:team_id>/', views.show_team, name='show-team'),
|
||||
path('team/<int:team_id>/', views.show_team_by_id, name='show-team'),
|
||||
path('team/<int:team_id>/+edit/', views.edit_team, name='edit-team'),
|
||||
path('team/<int:team_id>/+join/', event_views.join_team, name='join-team'),
|
||||
path('team/<int:team_id>/+leave/', event_views.leave_team, name='leave-team'),
|
||||
|
@ -109,6 +109,8 @@ urlpatterns = [
|
|||
path('about/', include('django.contrib.flatpages.urls')),
|
||||
|
||||
path('oauth/', include('social_django.urls', namespace='social')),
|
||||
|
||||
path('<str:team_slug>/', views.show_team_by_slug, name='show-team-by-slug'),
|
||||
]
|
||||
if settings.DEBUG:
|
||||
urlpatterns = urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
|
|
@ -114,7 +114,7 @@ def create_event(request, team_id):
|
|||
team = get_object_or_404(Team, id=team_id)
|
||||
if not request.user.profile.can_create_event(team):
|
||||
messages.add_message(request, messages.WARNING, message=_('You can not create events for this team.'))
|
||||
return redirect('show-team', team_id=team.pk)
|
||||
return redirect('show-team-by-slug', team_slug=team.slug)
|
||||
|
||||
new_event = Event(team=team, created_by=request.user.profile)
|
||||
|
||||
|
@ -669,10 +669,10 @@ def delete_event(request, event_id):
|
|||
elif request.method == 'POST':
|
||||
form = DeleteEventForm(request.POST)
|
||||
if form.is_valid() and form.cleaned_data['confirm']:
|
||||
team_id = event.team_id
|
||||
delete_event_searchable(event);
|
||||
team_slug = event.team.slug
|
||||
delete_event_searchable(event)
|
||||
event.delete()
|
||||
return redirect('show-team', team_id)
|
||||
return redirect('show-team-by-slug', team_slug)
|
||||
else:
|
||||
context = {
|
||||
'team': event.team,
|
||||
|
@ -734,9 +734,9 @@ def delete_series(request, series_id):
|
|||
elif request.method == 'POST':
|
||||
form = DeleteEventSeriesForm(request.POST)
|
||||
if form.is_valid() and form.cleaned_data['confirm']:
|
||||
team_id = series.team_id
|
||||
team_slug = series.team.slug
|
||||
series.delete()
|
||||
return redirect('show-team', team_id)
|
||||
return redirect('show-team-by-slug', team_slug)
|
||||
else:
|
||||
context = {
|
||||
'team': series.team,
|
||||
|
|
|
@ -15,6 +15,7 @@ from events.models.profiles import Organization, Team, UserProfile, Member
|
|||
from events.models.events import Event, CommonEvent, Place, Attendee
|
||||
from events.forms import TeamForm, NewTeamForm, DeleteTeamForm, TeamContactForm, TeamInviteForm
|
||||
from events import location
|
||||
from events.utils import slugify
|
||||
|
||||
from accounts.models import EmailRecord
|
||||
|
||||
|
@ -43,8 +44,18 @@ def teams_list_all(request, *args, **kwargs):
|
|||
}
|
||||
return render(request, 'get_together/teams/list_teams.html', context)
|
||||
|
||||
def show_team(request, team_id, *args, **kwargs):
|
||||
|
||||
def show_team_by_slug(request, team_slug):
|
||||
team = get_object_or_404(Team, slug=team_slug)
|
||||
return show_team(request, team)
|
||||
|
||||
|
||||
def show_team_by_id(request, team_id):
|
||||
team = get_object_or_404(Team, id=team_id)
|
||||
return redirect('show-team-by-slug', team_slug=team.slug)
|
||||
|
||||
|
||||
def show_team(request, team):
|
||||
upcoming_events = Event.objects.filter(team=team, end_time__gt=datetime.datetime.now()).order_by('start_time')
|
||||
recent_events = Event.objects.filter(team=team, end_time__lte=datetime.datetime.now()).order_by('-start_time')[:5]
|
||||
context = {
|
||||
|
@ -58,6 +69,7 @@ def show_team(request, team_id, *args, **kwargs):
|
|||
}
|
||||
return render(request, 'get_together/teams/show_team.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def create_team(request, *args, **kwargs):
|
||||
if request.method == 'GET':
|
||||
|
@ -74,7 +86,7 @@ def create_team(request, *args, **kwargs):
|
|||
new_team.owner_profile = request.user.profile
|
||||
new_team.save()
|
||||
Member.objects.create(team=new_team, user=request.user.profile, role=Member.ADMIN)
|
||||
return redirect('show-team', team_id=new_team.pk)
|
||||
return redirect('show-team-by-slug', team_slug=new_team.slug)
|
||||
else:
|
||||
context = {
|
||||
'team_form': form,
|
||||
|
@ -88,7 +100,7 @@ def edit_team(request, team_id):
|
|||
team = get_object_or_404(Team, id=team_id)
|
||||
if not request.user.profile.can_edit_team(team):
|
||||
messages.add_message(request, messages.WARNING, message=_('You can not make changes to this team.'))
|
||||
return redirect('show-team', team_id=team.pk)
|
||||
return redirect('show-team-by-slug', team_slug=team.slug)
|
||||
|
||||
if request.method == 'GET':
|
||||
form = TeamForm(instance=team)
|
||||
|
@ -104,7 +116,7 @@ def edit_team(request, team_id):
|
|||
new_team = form.save()
|
||||
new_team.owner_profile = request.user.profile
|
||||
new_team.save()
|
||||
return redirect('show-team', team_id=new_team.pk)
|
||||
return redirect('show-team-by-slug', team_slug=new_team.slug)
|
||||
else:
|
||||
context = {
|
||||
'team': team,
|
||||
|
@ -119,7 +131,7 @@ def delete_team(request, team_id):
|
|||
team = get_object_or_404(Team, id=team_id)
|
||||
if not request.user.profile.can_edit_team(team):
|
||||
messages.add_message(request, messages.WARNING, message=_('You can not make changes to this team.'))
|
||||
return redirect('show-team', team_id)
|
||||
return redirect('show-team-by-slug', team.slug)
|
||||
|
||||
if request.method == 'GET':
|
||||
form = DeleteTeamForm()
|
||||
|
@ -149,7 +161,7 @@ def manage_members(request, team_id):
|
|||
team = get_object_or_404(Team, id=team_id)
|
||||
if not request.user.profile.can_edit_team(team):
|
||||
messages.add_message(request, messages.WARNING, message=_('You can not manage this team\'s members.'))
|
||||
return redirect('show-team', team_id)
|
||||
return redirect('show-team-by-slug', team.slug)
|
||||
|
||||
members = Member.objects.filter(team=team).order_by('user__realname')
|
||||
member_choices = [(member.id, member.user) for member in members if member.user.user.account.is_email_confirmed]
|
||||
|
@ -162,7 +174,7 @@ def manage_members(request, team_id):
|
|||
body = contact_form.cleaned_data['body']
|
||||
if to is not 'admins' and not request.user.profile.can_edit_team(team):
|
||||
messages.add_message(request, messages.WARNING, message=_('You can not contact this team\'s members.'))
|
||||
return redirect('show-team', team_id)
|
||||
return redirect('show-team-by-slug', team.slug)
|
||||
if to == 'all':
|
||||
count = 0
|
||||
for member in Member.objects.filter(team=team):
|
||||
|
|
Loading…
Reference in a new issue