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

linting, documentation, and using first/last name instead of usernames

parent 5e62b403
No related branches found
No related tags found
No related merge requests found
......@@ -10,7 +10,8 @@ class NewUserForm(UserCreationForm):
class Meta:
model = User
fields = ("username", "email", "password1", "password2", "isProfessor")
fields = ("username", "email", "first_name", "last_name",
"password1", "password2", "isProfessor")
def save(self, commit=True):
user = super(NewUserForm, self).save(commit=False)
......@@ -28,6 +29,8 @@ class NewUserForm(UserCreationForm):
class NewProjectForm(forms.Form):
title = forms.CharField(label="Title", max_length=200)
description = forms.CharField(label="Description", max_length=2048)
status = forms.CharField(
label="Status", max_length=128, initial="Accepting applications")
tags = forms.CharField(widget=forms.HiddenInput(), required=False)
......
......@@ -35,6 +35,7 @@ h5 {
.undecorated-link {
text-decoration: none;
color: inherit;
}
#tagBox {
......
......@@ -21,7 +21,7 @@
</div>
{% if user.username %}
<div>
Logged in as {{user.username}}
Logged in as {{user.first_name}} {{user.last_name}}
<a href="/logout/"><button type="button">Sign out</button></a>
</div>
{% else %}
......@@ -34,6 +34,9 @@
</div>
{% endif %}
</div>
<div class="messagebox {{message_type}}">
{{message}}
</div>
{% block content %} {% endblock %}
</body>
</html>
......@@ -9,7 +9,7 @@
<ul>
{% for application in applications %}
<li class="dashed-box">
<b>{{application.student.username}}</b> on {{application.date_sent}}
<b>{{application.student.first_name}} {{application.student.last_name}}</b> on {{application.date_sent}}
<br>
{% if application.priority %}
<em>Priority: </em> {{application.priority}}
......
......@@ -3,7 +3,7 @@
{% block title %} {{project.title}} {% endblock %}
{% block content %}
<h1>{{project.title}}</h1>
<h3>{{project.professor}}</h3>
<h3>{{project.professor.first_name}} {{project.professor.last_name}}</h3>
{% if project.professor.id == user.id %}
<a href="/project/{{project.id}}/edit/">Edit this project</a>
{% endif %}
......@@ -14,7 +14,11 @@
{% if user|is_student %}
<a href="/project/{{project.id}}/apply/">Apply to this project</a>
{% endif %}
{% if project.professor.id == user.id %}
<p>(i) {{numApplicants}} students have applied so far. <a href="/project/{{project.id}}/edit/">View Applications.</a></p>
{% else %}
<p>(i) {{numApplicants}} students have applied so far.</p>
{% endif %}
{% if tags %}
<h4>Tags:</h4>
<ul id="tagBox">
......
......@@ -13,7 +13,7 @@
{% for project in projects %}
<li class="dashed-box">
<a href="{% url 'project_detail' project.id %}">{{ project.title }}</a>
by {{project.professor}}
by {{project.professor.first_name}} {{project.professor.last_name}}
<br/>
<em>Description: </em>{{project.description}}
<br/>
......@@ -56,7 +56,7 @@
{% else %}
<input type="checkbox" name="prof{{professor.id}}"/>
{% endif %}
<label for="prof{{professor.id}}">{{professor.username}}</label>
<label for="prof{{professor.id}}">{{professor.first_name}} {{professor.last_name}}</label>
<br/>
{% endfor %}
<input type="submit" value="Filter"/>
......
......@@ -44,7 +44,10 @@
</div>
{% endif %}
<div>
<b>{{application.project.title}}</b> by {{application.project.professor}}
<a href="/project/{{application.project.id}}" class="undecorated-link">
<b>{{application.project.title}}</b>
</a>
by {{application.project.professor.first_name}} {{application.project.professor.last_name}}
<br />
<em>Description: </em>{{application.project.description}}
<br/>
......
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import User
from django.http.response import Http404, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseRedirect
from django.http.response import HttpResponseBadRequest, HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect, render
from django.http import HttpResponse
from django.db.models import F
......@@ -12,54 +11,72 @@ from pasapp.models import Application, Project, ProjectTag, Tag
from pasapp.utils import contextWithHeader, is_professor, is_student
# Create your views here.
def index(request):
tagIds, professorIds = [], []
'''
Lists all active projects. Also handles filtering those projects via POST requests.
URL: /
'''
tag_ids, professor_ids = [], []
if request.method == "POST":
post_request = request.POST
# Sort the IDs sent by the filter post request into professor IDs and tag IDs
for key in post_request.keys():
if key.startswith("prof"):
professorIds.append(int(key.replace("prof", "", 1)))
professor_ids.append(int(key.replace("prof", "", 1)))
elif key.startswith("tag"):
tagIds.append(int(key.replace("tag", "", 1)))
tag_ids.append(int(key.replace("tag", "", 1)))
if tagIds:
projectTags = ProjectTag.objects.filter(tag_id__in=tagIds).all()
tagProjects = {relation.project for relation in projectTags}
# Within each filter section (e.g. tag filters), we OR each selected option.
# If no filters are selected for a section, we just return all projects.
if tag_ids:
project_tags = ProjectTag.objects.filter(tag_id__in=tag_ids).all()
tag_projects = {relation.project for relation in project_tags}
else:
tagProjects = Project.objects.all()
tag_projects = Project.objects.all()
if professorIds:
professorProjects = Project.objects.filter(
professor_id__in=professorIds).all()
if professor_ids:
professor_projects = Project.objects.filter(
professor_id__in=professor_ids).all()
else:
professorProjects = Project.objects.all()
professor_projects = Project.objects.all()
projects = tagProjects.intersection(professorProjects)
# The intersection of the results from each filtering option works like an AND
projects = tag_projects.intersection(professor_projects)
else:
projects = Project.objects.order_by('-title')
tags = ProjectTag.objects.all()
professors = {project.professor for project in Project.objects.all()}
print(professorIds)
context = {'projects': projects, 'tags': tags, 'professors': professors,
'selectedTags': tagIds, 'selectedProfessors': professorIds}
tag_filters = ProjectTag.objects.all()
# Only show professors who have published a project
professor_filters = {
project.professor for project in Project.objects.all()}
context = {'projects': projects, 'tags': tag_filters, 'professors': professor_filters,
'selectedTags': tag_ids, 'selectedProfessors': professor_ids}
return render(request, 'pasapp/projects.html', contextWithHeader(context, request))
def project_details(request, project_id):
'''
Shows more details about the given project, including number of applicants
URL: /project/<id>
'''
project = get_object_or_404(Project, pk=project_id)
numApplicants = Application.objects.filter(project=project_id).count()
num_applicants = Application.objects.filter(project=project_id).count()
tags = [entry.tag.name for entry in ProjectTag.objects.filter(
project=project).all()]
context = {'project': project,
'numApplicants': numApplicants, 'tags': tags}
'numApplicants': num_applicants, 'tags': tags}
return render(request, 'pasapp/project_details.html', contextWithHeader(context, request))
@login_required
@user_passes_test(is_student)
def apply(request, project_id):
'''
Form page that allows a student to apply for a project
URL: /project/<id>/apply
'''
project = get_object_or_404(Project, pk=project_id)
if request.method == 'POST':
form = ApplicationForm(request.POST)
......@@ -77,6 +94,10 @@ def apply(request, project_id):
@login_required
def project_applications(request, project_id):
'''
Shows all applications to a project (if you are the professor who owns that project)
URL: /project/<id>/applications
'''
project = get_object_or_404(Project, pk=project_id)
if not request.user.id == project.professor.id:
return HttpResponseForbidden()
......@@ -89,6 +110,10 @@ def project_applications(request, project_id):
@login_required
@user_passes_test(is_professor)
def create_project(request):
'''
Form page allowing professors to create a new project
URL: /project/create
'''
if request.method == 'POST':
form = NewProjectForm(request.POST)
if form.is_valid():
......@@ -120,6 +145,10 @@ def create_project(request):
@login_required
@user_passes_test(is_professor)
def edit_project(request, project_id):
'''
Form page that allows a professor to edit and existing project.
URL: /project/<id>/edit
'''
project = get_object_or_404(Project, pk=project_id)
if not request.user.id == project.professor.id:
return HttpResponseForbidden()
......@@ -129,29 +158,38 @@ def edit_project(request, project_id):
if form.is_valid():
title = form.cleaned_data.get('title')
description = form.cleaned_data.get('description')
status = form.cleaned_data.get('status')
project.title = title
project.description = description
project.status = status
project.save()
redirect("index")
else:
form = NewProjectForm(
initial={'title': project.title, 'description': project.description})
form = NewProjectForm(initial={
'title': project.title, 'description': project.description, 'status': project.status})
context = {'form': form, 'project': project}
return render(request, 'pasapp/edit_project.html', contextWithHeader(context, request))
@login_required
def my_applications(request):
'''
Displays all of the user's applications, rendered differently for students and professors (see below)
URL: /applications
'''
if is_student(request.user):
return student_applications_view(request)
elif is_professor(request.user):
return professor_applications_view(request)
else:
return HttpResponse("what")
return HttpResponse("Only students and professors may view this page.")
def student_applications_view(request):
'''
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(
F('priority').asc(nulls_last=True), '-date_sent')
context = {'applications': applications}
......@@ -159,6 +197,9 @@ def student_applications_view(request):
def professor_applications_view(request):
'''
Displays all applications to the professor's projects, grouped by project
'''
projects = Project.objects.filter(professor=request.user)
sections = {project: Application.objects.filter(
project=project).order_by('-date_sent') for project in projects}
......@@ -167,11 +208,15 @@ def professor_applications_view(request):
def update_priorities(request):
'''
Endpoint for updating the priority values of a student's applications. POST only.
URL: /applications/update_priorities
'''
if request.method == 'POST':
post_request = request.POST
for field in post_request:
if field.startswith("priority"):
applicationId = post_request[field]
application_id = post_request[field]
priority = int(field.replace("priority", "", 1))
duplicate_priority_applications = Application.objects.filter(
......@@ -180,9 +225,9 @@ def update_priorities(request):
application.priority = None
application.save()
if (applicationId == ''):
if application_id == '':
continue
application = Application.objects.get(pk=applicationId)
application = Application.objects.get(pk=application_id)
if application is not None:
application.priority = priority
application.save()
......@@ -193,6 +238,10 @@ def update_priorities(request):
def register(request):
'''
Form page for registering a new user.
URL: /register
'''
if request.method == 'POST':
form = NewUserForm(request.POST)
if form.is_valid():
......@@ -206,6 +255,11 @@ def register(request):
def login_view(request):
'''
Form page for logging a user in. Mostly used as a redirect if the user attempts to access
a page that requires login.
URL: /login
'''
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
print(form)
......@@ -224,5 +278,9 @@ def login_view(request):
def logout_view(request):
'''
Endpoint for logout requests. Logs the current user out and returns to the index page.
URL: /logout
'''
logout(request)
return redirect('index')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment