Skip to content

Commit

Permalink
Update org URL scheme from <id-slug> to <slug> (#334)
Browse files Browse the repository at this point in the history
Co-authored-by: Le Bao Hiep <baohiep2013@gmail.com>
  • Loading branch information
magnified103 and hieplpvip authored Sep 28, 2023
1 parent 49b5b09 commit 40192be
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 39 deletions.
6 changes: 4 additions & 2 deletions dmoj/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@ def paged_list_view(view, name):

path('organizations/', organization.OrganizationList.as_view(), name='organization_list'),
path('organizations/create', organization.CreateOrganization.as_view(), name='organization_create'),
path('organization/<int:pk>-<slug:slug>', include([
path('organization/<int:pk>-<path:suffix>',
lambda _, pk, suffix: HttpResponsePermanentRedirect('/organization/%s' % suffix)),
path('organization/<slug:slug>', include([
path('', organization.OrganizationHome.as_view(), name='organization_home'),
path('/users/', organization.OrganizationUsers.as_view(), name='organization_users'),
path('/join', organization.JoinOrganization.as_view(), name='join_organization'),
Expand Down Expand Up @@ -305,7 +307,7 @@ def paged_list_view(view, name):
path('new', organization.BlogPostCreateOrganization.as_view(), name='blog_post_create_organization'),
])),

path('/', lambda _, pk, slug: HttpResponsePermanentRedirect(reverse('organization_home', args=[pk, slug]))),
path('/', lambda _, slug: HttpResponsePermanentRedirect(reverse('organization_home', args=[slug]))),
])),

path('runtimes/', language.LanguageList.as_view(), name='runtime_list'),
Expand Down
19 changes: 19 additions & 0 deletions judge/migrations/0197_org_slugs_begin_with_letter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 3.2.20 on 2023-09-26 16:45

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('judge', '0196_view_all_user_comment_permission'),
]

operations = [
migrations.AlterField(
model_name='organization',
name='slug',
field=models.SlugField(help_text='Organization name shown in URLs.', max_length=128, unique=True, validators=[django.core.validators.RegexValidator('^[a-zA-Z]', 'Organization slugs must begin with a letter.')], verbose_name='organization slug'),
),
]
6 changes: 4 additions & 2 deletions judge/models/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class Organization(models.Model):
name = models.CharField(max_length=128, verbose_name=_('organization title'))
slug = models.SlugField(max_length=128, verbose_name=_('organization slug'),
help_text=_('Organization name shown in URLs.'),
validators=[RegexValidator(r'^[a-zA-Z]',
_('Organization slugs must begin with a letter.'))],
unique=True)
short_name = models.CharField(max_length=20, verbose_name=_('short name'),
help_text=_('Displayed beside user name during contests.'))
Expand Down Expand Up @@ -103,10 +105,10 @@ def __str__(self):
return self.name

def get_absolute_url(self):
return reverse('organization_home', args=(self.id, self.slug))
return reverse('organization_home', args=[self.slug])

def get_users_url(self):
return reverse('organization_users', args=(self.id, self.slug))
return reverse('organization_users', args=[self.slug])

class Meta:
ordering = ['name']
Expand Down
2 changes: 1 addition & 1 deletion judge/sitemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class OrganizationSitemap(Sitemap):
priority = 0.5

def items(self):
return Organization.objects.values_list('id', 'slug')
return Organization.objects.values_list('slug')

def location(self, obj):
return reverse('organization_home', args=obj)
Expand Down
24 changes: 10 additions & 14 deletions judge/views/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class BaseOrganizationListView(OrganizationMixin, ListView):
slug_url_kwarg = 'slug'

def get_object(self):
return get_object_or_404(Organization, id=self.kwargs.get('pk'))
return get_object_or_404(Organization, slug=self.kwargs.get('slug'))

def get_context_data(self, **kwargs):
return super().get_context_data(organization=self.object, **kwargs)
Expand Down Expand Up @@ -119,7 +119,7 @@ def get_context_data(self, **kwargs):
context['users'] = ranker(context['users'])
context['partial'] = True
context['is_admin'] = self.can_edit_organization()
context['kick_url'] = reverse('organization_user_kick', args=[self.object.id, self.object.slug])
context['kick_url'] = reverse('organization_user_kick', args=[self.object.slug])
context['first_page_href'] = '.'
context.update(self.get_sort_context())
context.update(self.get_sort_paginate_context())
Expand Down Expand Up @@ -174,8 +174,6 @@ class OrganizationRequestForm(Form):

class RequestJoinOrganization(LoginRequiredMixin, SingleObjectMixin, FormView):
model = Organization
slug_field = 'key'
slug_url_kwarg = 'key'
template_name = 'organization/requests/request.html'
form_class = OrganizationRequestForm

Expand All @@ -201,7 +199,7 @@ def form_valid(self, form):
request.state = 'P'
request.save()
return HttpResponseRedirect(reverse('request_organization_detail', args=(
request.organization.id, request.organization.slug, request.id,
request.organization.slug, request.id,
)))


Expand All @@ -224,8 +222,6 @@ def get_object(self, queryset=None):

class OrganizationRequestBaseView(LoginRequiredMixin, SingleObjectTemplateResponseMixin, SingleObjectMixin, View):
model = Organization
slug_field = 'key'
slug_url_kwarg = 'key'
tab = None

def get_object(self, queryset=None):
Expand Down Expand Up @@ -432,9 +428,9 @@ def get_context_data(self, **kwargs):
return context

def dispatch(self, request, *args, **kwargs):
if 'pk' not in kwargs:
raise ImproperlyConfigured('Must pass a pk')
self.organization = get_object_or_404(Organization, pk=kwargs['pk'])
if 'slug' not in kwargs:
raise ImproperlyConfigured('Must pass a slug')
self.organization = get_object_or_404(Organization, slug=kwargs['slug'])
self.object = self.organization

if not self.allow_all_users and \
Expand All @@ -456,9 +452,9 @@ def can_edit_organization(self, org=None):

class CustomAdminOrganizationMixin(CustomOrganizationMixin):
def dispatch(self, request, *args, **kwargs):
if 'pk' not in kwargs:
raise ImproperlyConfigured('Must pass a pk')
self.organization = get_object_or_404(Organization, pk=kwargs['pk'])
if 'slug' not in kwargs:
raise ImproperlyConfigured('Must pass a slug')
self.organization = get_object_or_404(Organization, slug=kwargs['slug'])
if self.can_edit_organization():
return super(CustomAdminOrganizationMixin, self).dispatch(request, *args, **kwargs)
raise PermissionDenied
Expand Down Expand Up @@ -503,7 +499,7 @@ def get_queryset(self):

def get_context_data(self, **kwargs):
context = super(OrganizationHome, self).get_context_data(**kwargs)
context['first_page_href'] = reverse('organization_home', args=[self.object.pk, self.object.slug])
context['first_page_href'] = reverse('organization_home', args=[self.object.slug])
context['title'] = self.object.name
context['can_edit'] = self.can_edit_organization()
context['is_member'] = self.request.profile in self.object
Expand Down
4 changes: 4 additions & 0 deletions locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -2329,6 +2329,10 @@ msgstr ""
msgid "Organization name shown in URL"
msgstr ""

#: judge/models/profile.py:45
msgid "Organization slugs must begin with a letter."
msgstr ""

#: judge/models/profile.py:45
msgid "Displayed beside user name during contests"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions locale/vi/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -2422,6 +2422,10 @@ msgstr "tên viết tắt trên đường dẫn"
msgid "Organization name shown in URLs."
msgstr "Tên viết tắt của tổ chức, được dùng trong đường dẫn tới tổ chức"

#: judge/models/profile.py:45
msgid "Organization slugs must begin with a letter."
msgstr "Tên viết tắt của tổ chức phải bắt đầu bằng một chữ cái."

#: judge/models/profile.py:45
msgid "Displayed beside user name during contests."
msgstr "Hiển thị bên cạnh tên trong các kỳ thi"
Expand Down
12 changes: 6 additions & 6 deletions templates/organization/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,37 +89,37 @@ <h3>{{ _('Controls') }} <i class="fa fa-question-circle"></i></h3>
<div class="sidebox-content" style="padding: 1em;">
{% if request.user.is_authenticated %}
{% if is_member %}
<form method="post" action="{{ url('leave_organization', organization.id, organization.slug) }}">
<form method="post" action="{{ url('leave_organization', organization.slug) }}">
{% csrf_token %}
<input type="submit" class="unselectable button full leave-organization" value="{{ _('Leave organization') }}">
</form>
{% elif organization.is_open %}
<form method="post" action="{{ url('join_organization', organization.id, organization.slug) }}">
<form method="post" action="{{ url('join_organization', organization.slug) }}">
{% csrf_token %}
<input type="submit" class="unselectable button full" value="{{ _('Join organization') }}">
</form>
{% else %}
<a href="{{ url('request_organization', organization.id, organization.slug) }}"
<a href="{{ url('request_organization', organization.slug) }}"
class="unselectable button full">{{ _('Request membership') }}</a>
{% endif %}
{% endif %}
<br>
{% if can_edit %}
{% if not organization.is_open %}
<div>
<a href="{{ url('organization_requests_pending', organization.id, organization.slug) }}">
<a href="{{ url('organization_requests_pending', organization.slug) }}">
{{ _('View requests') }}
{% if num_requests %}<span class="badge">{{ num_requests }}</span>{% endif %}
</a>
</div>
{% endif %}
{% if perms.judge.edit_organization_post %}
<div>
<a href="{{ url('blog_post_create_organization', organization.id, organization.slug) }}">{{ _('Create blog post') }}</a>
<a href="{{ url('blog_post_create_organization', organization.slug) }}">{{ _('Create blog post') }}</a>
</div>
{% endif %}
<div>
<a href="{{ url('edit_organization', organization.id, organization.slug) }}">{{ _('Edit organization') }}</a>
<a href="{{ url('edit_organization', organization.slug) }}">{{ _('Edit organization') }}</a>
</div>
{% endif %}
{% if perms.judge.change_organization %}
Expand Down
2 changes: 1 addition & 1 deletion templates/organization/requests/log.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<tr id="request-{{ r.id }}">
<td>{{ link_user(r.user) }}</td>
<td>
<a href="{{ url('request_organization_detail', object.id, object.slug, r.id) }}">
<a href="{{ url('request_organization_detail', object.slug, r.id) }}">
{{- r.time|date(_("N j, Y, H:i")) -}}
</a>
</td>
Expand Down
4 changes: 2 additions & 2 deletions templates/organization/requests/pending.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{% for form in formset %}
<tr id="request-{{ form.instance.id }}">
<td>{{ form.id }}{{ link_user(form.instance.user) }}</td>
<td><a href="{{ url('request_organization_detail', object.id, object.slug, form.instance.id) }}">
<td><a href="{{ url('request_organization_detail', object.slug, form.instance.id) }}">
{{ form.instance.time|date(_("N j, Y, H:i")) }}
</a></td>
<td>{{ form.state }}</td>
Expand All @@ -36,4 +36,4 @@
{% else %}
<p>{{ _('There are no requests to approve.') }}</p>
{% endif %}
{% endblock %}
{% endblock %}
10 changes: 5 additions & 5 deletions templates/organization/requests/tabs.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<div class="tabs">
<ul>
<li{% if tab == 'pending' %} class="active"{% endif %}>
<a href="{{ url('organization_requests_pending', object.id, object.slug) }}">{{ _('Pending') }}</a>
<a href="{{ url('organization_requests_pending', object.slug) }}">{{ _('Pending') }}</a>
</li>
<li{% if tab == 'log' %} class="active"{% endif %}>
<a href="{{ url('organization_requests_log', object.id, object.slug) }}">{{ _('Log') }}</a>
<a href="{{ url('organization_requests_log', object.slug) }}">{{ _('Log') }}</a>
</li>
<li{% if tab == 'approved' %} class="active"{% endif %}>
<a href="{{ url('organization_requests_approved', object.id, object.slug) }}">{{ _('Approved') }}</a>
<a href="{{ url('organization_requests_approved', object.slug) }}">{{ _('Approved') }}</a>
</li>
<li{% if tab == 'rejected' %} class="active"{% endif %}>
<a href="{{ url('organization_requests_rejected', object.id, object.slug) }}">{{ _('Rejected') }}</a>
<a href="{{ url('organization_requests_rejected', object.slug) }}">{{ _('Rejected') }}</a>
</li>
</ul>
</div>
</div>
12 changes: 6 additions & 6 deletions templates/organization/tabs.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ <h2>{{ content_title or title }}</h2>
<br>
<div class="tabs">
<ul>
{{ make_tab('home', 'fa-info-circle', url('organization_home', organization.pk, organization.slug), _('Home')) }}
{{ make_tab('home', 'fa-info-circle', url('organization_home', organization.slug), _('Home')) }}
{{ make_tab('users', 'fa-university', organization.get_users_url(), _('Users')) }}
{{ make_tab('problem-list', 'fa-puzzle-piece', url('problem_list_organization', organization.pk, organization.slug), _('Problems list')) }}
{{ make_tab('contest-list', 'fa-trophy', url('contest_list_organization', organization.pk, organization.slug), _('Contests list')) }}
{{ make_tab('submission-list', 'fa-list', url('submission_list_organization', organization.pk, organization.slug), _('Submissions')) }}
{{ make_tab('problem-list', 'fa-puzzle-piece', url('problem_list_organization', organization.slug), _('Problems list')) }}
{{ make_tab('contest-list', 'fa-trophy', url('contest_list_organization', organization.slug), _('Contests list')) }}
{{ make_tab('submission-list', 'fa-list', url('submission_list_organization', organization.slug), _('Submissions')) }}
</ul>
<span class="spacer"></span>
<ul>
{% if organization.is_admin(request.profile) %}
{% if request.user.has_perm('judge.create_organization_problem') %}
{{ make_tab('create', 'fa-plus', url('problem_create_organization', organization.id, organization.slug), _('Create new problem')) }}
{{ make_tab('create', 'fa-plus', url('problem_create_organization', organization.slug), _('Create new problem')) }}
{% endif %}
{% if request.user.has_perm('judge.create_private_contest') %}
{{ make_tab('create', 'fa-plus', url('contest_create_organization', organization.id, organization.slug), _('Create new contest')) }}
{{ make_tab('create', 'fa-plus', url('contest_create_organization', organization.slug), _('Create new contest')) }}
{% endif %}
{% endif %}
</ul>
Expand Down

0 comments on commit 40192be

Please sign in to comment.