Skip to content

Commit f80d0c6

Browse files
#M21. Add functionality to set maximum number of registrations. (#201)
1 parent 0a23612 commit f80d0c6

14 files changed

Lines changed: 130 additions & 53 deletions

File tree

accounts/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
urlpatterns = [
66
path("edit_profile/", views.edit_profile, name="edit_profile"),
7-
path('admin/', LoginView.as_view()),
7+
path('external/', LoginView.as_view()),
88
]

hackathon/forms.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class HackathonForm(forms.ModelForm):
7575
team_size = forms.IntegerField(
7676
label="Team Size",
7777
required=True,
78-
widget=forms.TextInput(attrs={'min':3,'max': 6,'type': 'number'})
78+
widget=forms.TextInput(attrs={'min': 3, 'max': 6, 'type': 'number'})
7979
)
8080
organisation = forms.ModelChoiceField(
8181
label="Organisation",
@@ -88,12 +88,17 @@ class HackathonForm(forms.ModelForm):
8888
})
8989
)
9090
is_public = forms.BooleanField(required=False)
91+
max_participants = forms.IntegerField(
92+
label="Max Number Of Participants (leave empty for no max)",
93+
required=False,
94+
widget=forms.TextInput({'type': 'number'})
95+
)
9196

9297
class Meta:
9398
model = Hackathon
9499
fields = ['display_name', 'description', 'theme', 'start_date',
95100
'end_date', 'status', 'organisation', 'score_categories',
96-
'team_size', 'tag_line', 'is_public',
101+
'team_size', 'tag_line', 'is_public', 'max_participants',
97102
]
98103

99104
def __init__(self, *args, **kwargs):
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 3.1.8 on 2021-07-17 16:54
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('hackathon', '0043_hackathon_is_public'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='hackathon',
15+
name='max_participants',
16+
field=models.IntegerField(blank=True, default=None, null=True),
17+
),
18+
migrations.AlterField(
19+
model_name='hackathon',
20+
name='theme',
21+
field=models.CharField(default='', max_length=264),
22+
),
23+
]

hackathon/models.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ class Hackathon(models.Model):
5050
related_name='judged_hackathons')
5151
# Hackathons can have multiple participants judges and
5252
# users could be participating in more than one Hackathon: Many to Many
53-
participants = models.ManyToManyField(User,
54-
blank=True,
55-
related_name='participated_hackathons')
53+
participants = models.ManyToManyField(
54+
User, blank=True, related_name='participated_hackathons')
5655
# Hackathons can have multiple score categories and score categories
5756
# Can belong to multiple hackahtons: Many to Many
5857
score_categories = models.ManyToManyField(
@@ -82,6 +81,7 @@ class Hackathon(models.Model):
8281
help_text=("Hackathon image.")
8382
)
8483
is_public = models.BooleanField(default=False)
84+
max_participants = models.IntegerField(default=None, null=True, blank=True)
8585

8686
def __str__(self):
8787
return self.display_name
@@ -90,6 +90,12 @@ class Meta:
9090
verbose_name = "Hackathon"
9191
verbose_name_plural = "Hackathons"
9292

93+
def max_participants_reached(self):
94+
if not self.max_participants:
95+
return False
96+
97+
return self.participants.count() >= self.max_participants
98+
9399

94100
class HackAwardCategory(models.Model):
95101
"""Model representing a HackAwardCategory which represents a type of award

hackathon/templates/hackathon/create-event.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@ <h1>Create Hackathon</h1>
5555
<div class="col-12 mb-3">
5656
{{ form.score_categories|as_crispy_field }}
5757
</div>
58-
<div class="col-12 mb-3">
58+
<div class="col-12 col-md-6 mb-3">
5959
{{ form.is_public|as_crispy_field }}
6060
</div>
61+
<div class="col-12 col-md-6 mb-3">
62+
{{ form.max_participants|as_crispy_field }}
63+
</div>
6164
<div class="col-12 mb-5">
6265
<input type="submit" class="btn-ci mr-2">
6366
<a href="{% url 'hackathon:hackathon-list' %}" type="button" class="btn-ci button">Cancel</a>

hackathon/templates/hackathon/hackathon_view.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,13 @@
9898
{% if request.user.user_type|is_types:authorised_types %}
9999
<p class="hackathon-sub-details"><i class="far fa-question-circle"></i> Status: {{ hackathon.status }}</p>
100100
<p class="hackathon-sub-details"><i class="fas fa-chalkboard-teacher"></i> Organiser: {{ hackathon.organiser }}</p>
101+
<p class="hackathon-sub-details"><i class="fas fa-users"></i>
102+
Max Participants: {% if hackathon.max_participants %}{{ hackathon.max_participants }}{% else %}Unlimited{% endif %}
103+
{% if hackathon.max_participants_reached %}(Max Reached){% endif %}
104+
</p>
101105
{% else %}
102-
<p class="hackathon-sub-details"><i class="far fa-question-circle"></i> Status: {{hackathon.status|prettify_status}}</p>
106+
<p class="hackathon-sub-details"><i class="far fa-question-circle"></i> Status:
107+
{{hackathon.status|prettify_status:hackathon.max_participants_reached}}</p>
103108
{% endif %}
104109
<p class="hackathon-sub-details"><i class="far fa-clock"></i> Start: {{ hackathon.start_date }}</p>
105110
<p class="hackathon-sub-details"><i class="fas fa-clock"></i> End: {{ hackathon.end_date }}</p>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% if not hackathon.max_participants_reached %}
2+
<form id="enroll-form" action="{% url 'hackathon:enroll_toggle' %}" method="POST">
3+
{% csrf_token %}
4+
<input type="hidden" name="hackathon-id" value="{{ hackathon.id }}">
5+
<button id="enroll-part" type="submit"
6+
class="btn btn-ci mt-4 mb-2 form-control">
7+
<i class="fas fa-user-plus mr-2"></i>Enroll as Participant
8+
</button>
9+
</form>
10+
{% endif %}

hackathon/templates/hackathon/includes/enrollpart.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{% load custom_tags %}
22

3-
{% if hackathon.status == 'registration_open' %}
3+
{% if hackathon.status == 'registration_open' and not hackathon.max_participants_reached %}
44
<form id="enroll-form" action="{% url 'hackathon:enroll_toggle' %}" method="POST">
55
{% csrf_token %}
66
<!--It only sends the hackathon ID.-->

hackathon/templates/hackathon/includes/hackathon_card.html

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,14 @@ <h5 class="p-orange card-title"><a href="/hackathon/{{hackathon.id}}/" class="ci
3131
<p class="card-subtitle mb-2 text-muted"><i class="fas fa-user-plus p-2"></i>Registration closed for this hackathon</p>
3232
{% endif %}
3333
{% else %}
34-
{% if hackathon.status == 'registration_open' and request.user not in hackathon.participants.all %}
35-
<p class="card-subtitle mb-2 ci-orange"><i class="fas fa-user-plus p-2"></i>Registrations open!</p>
36-
{% elif hackathon.status == 'registration_open' and request.user in hackathon.participants.all %}
37-
<p class="card-subtitle mb-2 ci-orange"><i class="fas fa-user p-2"></i>You are enrolled in this hackathon!</p>
34+
{% if hackathon.status == 'registration_open' %}
35+
{% if hackathon.max_participants_reached %}
36+
<p class="card-subtitle mb-2 text-muted"><i class="fas fa-user-plus p-2"></i>Registrations closed.</p>
37+
{% elif request.user not in hackathon.participants.all %}
38+
<p class="card-subtitle mb-2 ci-orange"><i class="fas fa-user-plus p-2"></i>Registrations open!</p>
39+
{% elif request.user in hackathon.participants.all %}
40+
<p class="card-subtitle mb-2 ci-orange"><i class="fas fa-user p-2"></i>You are enrolled in this hackathon!</p>
41+
{% endif %}
3842
{% elif hackathon.status == 'hack_in_progress' or hackathon.status == 'judging' or hackathon.status == 'hack_prep' %}
3943
{% if request.user in hackathon.participants.all %}
4044
<p class="card-subtitle mb-2 ci-orange"><i class="fas fa-user-plus p-2"></i>You are participating in this hackathon</p>
@@ -59,7 +63,7 @@ <h5 class="p-orange card-title"><a href="/hackathon/{{hackathon.id}}/" class="ci
5963
{% endif %}
6064
<a href="{% url 'hackathon:view_hackathon' hackathon.id %}" class="btn btn-ci mr-3">Read More</a>
6165
{% if request.user.is_authenticated and hackathon.status == 'registration_open' and not request.user.user_type|is_types:authorised_types_on_card and request.user not in hackathon.participants.all %}
62-
<div class="enroll-hackathon-card">{% include 'hackathon/includes/enrollpart.html' %}</div>
66+
<div class="enroll-hackathon-card">{% include 'hackathon/includes/enroll_card.html' %}</div>
6367
{% endif %}
6468
{% endwith %}
6569

hackathon/templatetags/custom_tags.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ def place_identifier(num):
7272

7373

7474
@register.filter
75-
def prettify_status(status):
75+
def prettify_status(status, max_participants_reached):
7676
if status == 'published' or status == 'draft':
7777
return "Registration Starts Soon"
78-
elif status == 'registration_open':
78+
elif status == 'registration_open' and not max_participants_reached:
7979
return "Registration Open"
80+
elif status == 'registration_open' and max_participants_reached:
81+
return "Registration Closed"
8082
elif status == 'hack_prep':
8183
return "Hackathon Starting Soon"
8284
elif status == 'hack_in_progress':

0 commit comments

Comments
 (0)