Skip to content
Snippets Groups Projects
Commit 68a41616 authored by Odin Johan Vatne's avatar Odin Johan Vatne
Browse files

Add capacity, fix model fields

parent b7f2cc69
Branches
No related tags found
No related merge requests found
...@@ -30,6 +30,7 @@ class NewProjectForm(forms.Form): ...@@ -30,6 +30,7 @@ class NewProjectForm(forms.Form):
title = forms.CharField(label="Title", max_length=200, widget=forms.Textarea) title = forms.CharField(label="Title", max_length=200, widget=forms.Textarea)
description = forms.CharField( description = forms.CharField(
label="Description", max_length=2048, widget=forms.Textarea) label="Description", max_length=2048, widget=forms.Textarea)
capacity = forms.IntegerField(label="Expected capacity of students/groups that can work on this project:", required=False)
status = forms.CharField( status = forms.CharField(
label="Status", max_length=128, initial="Open", widget=forms.HiddenInput) label="Status", max_length=128, initial="Open", widget=forms.HiddenInput)
hidden = forms.BooleanField( hidden = forms.BooleanField(
......
# Generated by Django 3.2.9 on 2022-05-29 19:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pasapp', '0020_auto_20220521_0221'),
]
operations = [
migrations.AddField(
model_name='project',
name='capacity',
field=models.IntegerField(blank=True, default=None, null=True),
),
]
# Generated by Django 3.2.9 on 2022-05-29 20:09
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('pasapp', '0021_project_capacity'),
]
operations = [
migrations.AlterField(
model_name='application',
name='date_created',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='application',
name='last_updated',
field=models.DateTimeField(auto_now=True),
),
migrations.AlterField(
model_name='comment',
name='date_created',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='project',
name='date_created',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='project',
name='last_updated',
field=models.DateTimeField(auto_now=True),
),
]
# Generated by Django 3.2.9 on 2022-05-29 20:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('pasapp', '0022_auto_20220529_2209'),
]
operations = [
migrations.AlterField(
model_name='application',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pasapp.project'),
),
]
from django.db import models from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.timezone import now
class Project(models.Model): class Project(models.Model):
title = models.CharField(max_length=200) title = models.CharField(max_length=200)
...@@ -9,10 +10,11 @@ class Project(models.Model): ...@@ -9,10 +10,11 @@ class Project(models.Model):
group_size = models.CharField(max_length=128, blank=True, null=True) # TODO: Not implemented group_size = models.CharField(max_length=128, blank=True, null=True) # TODO: Not implemented
status = models.CharField(max_length=128, default="Draft") status = models.CharField(max_length=128, default="Draft")
hidden = models.BooleanField(default=True) # only in effect if status is custom hidden = models.BooleanField(default=True) # only in effect if status is custom
capacity = models.IntegerField(default=None, blank=True, null=True)
date_created = models.DateTimeField( date_created = models.DateTimeField(
auto_now_add=True, name='date_created') default=now, name='date_created')
last_updated = models.DateTimeField( last_updated = models.DateTimeField(
auto_now_add=True, name='last_updated') # TODO: Not implemented auto_now=True, name='last_updated')
# Tags - see ProjectTag below # Tags - see ProjectTag below
class Meta: class Meta:
...@@ -48,12 +50,12 @@ class Application(models.Model): ...@@ -48,12 +50,12 @@ class Application(models.Model):
def professor_status_label(self): def professor_status_label(self):
return Application.ProfessorStatus(self.professor_status).label return Application.ProfessorStatus(self.professor_status).label
project = models.ForeignKey(Project, on_delete=models.SET_NULL, null=True) project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
student = models.ForeignKey(User, on_delete=models.CASCADE) student = models.ForeignKey(User, on_delete=models.CASCADE)
message = models.CharField(max_length=2048) message = models.CharField(max_length=2048)
date_created = models.DateTimeField(auto_now_add=True, name='date_created') date_created = models.DateTimeField(default=now, name='date_created')
last_updated = models.DateTimeField( last_updated = models.DateTimeField(
auto_now_add=True, name='last_updated') # TODO: Not implemented auto_now=True, name='last_updated')
priority = models.IntegerField(default=None, blank=True, null=True) priority = models.IntegerField(default=None, blank=True, null=True)
professor_status = models.CharField(max_length=4, choices=ProfessorStatus.choices, default=ProfessorStatus.NONE, null=False) professor_status = models.CharField(max_length=4, choices=ProfessorStatus.choices, default=ProfessorStatus.NONE, null=False)
student_status = models.CharField(max_length=4, choices=StudentStatus.choices, default=StudentStatus.APPLIED, null=False) student_status = models.CharField(max_length=4, choices=StudentStatus.choices, default=StudentStatus.APPLIED, null=False)
...@@ -76,7 +78,7 @@ class Application(models.Model): ...@@ -76,7 +78,7 @@ class Application(models.Model):
class Comment(models.Model): class Comment(models.Model):
application = models.ForeignKey(Application, on_delete=models.CASCADE) application = models.ForeignKey(Application, on_delete=models.CASCADE)
sender = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) sender = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
date_created = models.DateTimeField(auto_now_add=True, name='date_created') date_created = models.DateTimeField(default=now, name='date_created')
message = models.CharField(max_length=2048) message = models.CharField(max_length=2048)
class Meta: class Meta:
......
...@@ -10,7 +10,12 @@ ...@@ -10,7 +10,12 @@
{% block content %} {% block content %}
{% for project, applications in sections.items %} {% for project, applications in sections.items %}
<a href="/project/{{project.id}}/" class="undecorated-link underline-hover"><h2>{{project.title}}</h2></a> <a href="/project/{{project.id}}/" class="undecorated-link underline-hover"><h2>{{project.title}}</h2></a>
<div>{{project.description}}</div> <div>
{{project.description}}<br>
{% if project.capacity %}
<b>Expected capacity: </b>{{project.capacity}}
{% endif %}
</div>
{% if applications %} {% if applications %}
{% load html_components %} {% load html_components %}
{% application_list_professor_interactive applications comments comment_box=True %} {% application_list_professor_interactive applications comments comment_box=True %}
......
...@@ -17,7 +17,12 @@ ...@@ -17,7 +17,12 @@
<p>{{project.description}}</p> <p>{{project.description}}</p>
<em>Status: </em>{{project.status}} <em>Status: </em>{{project.status}}
<br /> <br />
<p><span class="i">🛈</span> {{applications.count}} students have applied so far.</p> <p>
<span class="i">🛈</span> {{applications.count}} students have applied so far.<br>
{% if project.capacity %}
Expected capacity: {{project.capacity}}
{% endif %}
</p>
{% if projectTags %} {% if projectTags %}
<b>Tags:</b> <b>Tags:</b>
{% tagbox_categorized projectTags %} {% tagbox_categorized projectTags %}
......
...@@ -30,7 +30,11 @@ ...@@ -30,7 +30,11 @@
<br/> <br/>
{{project.description}} {{project.description}}
<br/> <br/>
<b>Status: </b>{{project.status}} <span><b>Status: </b>{{project.status}}</span> &emsp;
| {{applicationInfo|get:project.id|at:1}} applications / {{applicationInfo|get:project.id|at:0}} offered
{% if project.capacity %}
/ {{project.capacity}} capacity
{% endif %}
<br/> <br/>
{% tagbox_static projectTags|for_project:project %} {% tagbox_static projectTags|for_project:project %}
</li> </li>
......
...@@ -23,7 +23,15 @@ ...@@ -23,7 +23,15 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
<p><span class="i">🛈</span> {{numApplicants}} students have applied so far.</p> <p>
<span class="i">🛈</span> {{numApplicants}} students have applied so far. <br>
{% if numOffered %}
Offers extended: {{numOffered}}<br>
{% endif %}
{% if project.capacity %}
Expected capacity: {{project.capacity}}
{% endif %}
</p>
{% if projectTags %} {% if projectTags %}
<b>Tags:</b> <b>Tags:</b>
{% tagbox_categorized projectTags %} {% tagbox_categorized projectTags %}
......
...@@ -52,3 +52,7 @@ def for_application(comments, application): ...@@ -52,3 +52,7 @@ def for_application(comments, application):
@register.filter(name='get') @register.filter(name='get')
def get(map, key): def get(map, key):
return map[key] if key in map else '' return map[key] if key in map else ''
@register.filter(name='at')
def indexable_at(tuple, index):
return tuple[index]
\ No newline at end of file
...@@ -92,12 +92,19 @@ def index(request): ...@@ -92,12 +92,19 @@ def index(request):
projects = projects.exclude(id__in=cat_project_ids) projects = projects.exclude(id__in=cat_project_ids)
project_tags = project_tags.exclude(project_id__in=cat_project_ids) project_tags = project_tags.exclude(project_id__in=cat_project_ids)
application_info = {}
for project in projects:
open_apps = Application.objects.filter(project=project).exclude(app_closed_query)
offered = open_apps.filter(professor_status='OFFR')
application_info[project.id] = (offered.count(), open_apps.count())
tag_filters = Tag.objects.all() tag_filters = Tag.objects.all()
# Only show professors who have published a project # Only show professors who have published a project
professor_filters = { professor_filters = {
project.professor for project in get_open_projects()} project.professor for project in get_open_projects()}
context = {'projects': projects, 'projectTags': project_tags, 'allTags': tag_filters, 'professors': professor_filters, context = {'projects': projects, 'projectTags': project_tags, 'applicationInfo': application_info,
'allTags': tag_filters, 'professors': professor_filters,
'selectedTags': selected_tags, 'selectedProfessors': included_professor_ids} 'selectedTags': selected_tags, 'selectedProfessors': included_professor_ids}
return render(request, 'pasapp/pages/projects.html', contextWithHeader(context, request)) return render(request, 'pasapp/pages/projects.html', contextWithHeader(context, request))
...@@ -114,12 +121,14 @@ def project_details(request, project_id): ...@@ -114,12 +121,14 @@ def project_details(request, project_id):
def student_project_details(request, project_id): def student_project_details(request, project_id):
project = get_object_or_404(Project, pk=project_id) project = get_object_or_404(Project, pk=project_id)
num_applicants = Application.objects.filter(project=project_id).count() apps = Application.objects.filter(project=project_id)
num_applicants = apps.count()
num_offered = apps.filter(professor_status='OFFR').exclude(app_closed_query).count()
student_application = Application.objects.filter(project=project_id, student=request.user).first() if is_student(request.user) else None student_application = Application.objects.filter(project=project_id, student=request.user).first() if is_student(request.user) else None
project_tags = ProjectTag.objects.filter(project=project) project_tags = ProjectTag.objects.filter(project=project)
project_tags = [pair.tag for pair in project_tags] project_tags = [pair.tag for pair in project_tags]
comments = Comment.objects.filter(application=student_application) comments = Comment.objects.filter(application=student_application)
context = {'project': project, 'numApplicants': num_applicants, 'projectTags': project_tags, 'student_application': student_application, 'comments': comments} context = {'project': project, 'numApplicants': num_applicants, 'numOffered': num_offered, 'projectTags': project_tags, 'student_application': student_application, 'comments': comments}
return render(request, 'pasapp/pages/student_project_details.html', contextWithHeader(context, request)) return render(request, 'pasapp/pages/student_project_details.html', contextWithHeader(context, request))
def professor_project_details(request, project_id): def professor_project_details(request, project_id):
...@@ -207,13 +216,14 @@ def create_project(request): ...@@ -207,13 +216,14 @@ def create_project(request):
if form.is_valid(): if form.is_valid():
title = form.cleaned_data.get('title') title = form.cleaned_data.get('title')
description = form.cleaned_data.get('description') description = form.cleaned_data.get('description')
capacity = form.cleaned_data.get('capacity')
professor = request.user professor = request.user
status = form.cleaned_data.get('status') status = form.cleaned_data.get('status')
if status in DEFAULT_STATUSES: if status in DEFAULT_STATUSES:
hidden = False if status == OPEN_STATUS else True hidden = False if status == OPEN_STATUS else True
else: else:
hidden = form.cleaned_data.get('hidden') hidden = form.cleaned_data.get('hidden')
project = Project(title=title, description=description, project = Project(title=title, description=description, capacity=capacity,
status=status, hidden=hidden, professor=professor) status=status, hidden=hidden, professor=professor)
project.save() project.save()
...@@ -378,11 +388,14 @@ def student_applications_view(request): ...@@ -378,11 +388,14 @@ def student_applications_view(request):
''' '''
Displays all of the student's project applications and allows them to set rankings (see update_priorities below) Displays all of the student's project applications and allows them to set rankings (see update_priorities below)
''' '''
applications = Application.objects.filter(student=request.user).order_by( applications = Application.objects.filter(student=request.user)
F('priority').asc(nulls_last=True), '-date_created')
closed_applications = applications.filter(app_closed_query)
applications = applications.exclude(app_closed_query)
offered_applications = applications.filter(professor_status=Application.ProfessorStatus.OFFERED) offered_applications = applications.filter(professor_status=Application.ProfessorStatus.OFFERED)
open_applications = applications.filter(professor_status=Application.ProfessorStatus.NONE) open_applications = applications.filter(professor_status=Application.ProfessorStatus.NONE)
closed_applications = applications.filter(professor_status=Application.ProfessorStatus.DECLINED)
comments = Comment.objects.filter(application__in=applications) comments = Comment.objects.filter(application__in=applications)
context = {'applications': applications, 'offeredApplications': offered_applications, context = {'applications': applications, 'offeredApplications': offered_applications,
'openApplications': open_applications, 'closedApplications': closed_applications, 'openApplications': open_applications, 'closedApplications': closed_applications,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment