Skip to content

Commit f021d14

Browse files
Enhance cadmin with link styling, Django admin shortcuts, and project submission editing (#133)
* Initial plan * Add cadmin link styling and Django admin links - Changed cadmin link from button to plain link in course.html - Added Django admin links to course_admin.html for Course, Homework, and Project - Registered ProjectSubmission in Django admin to allow editing results after evaluation Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> * Implement cadmin improvements per new requirements - Move cadmin link to separate line in course.html - Remove ProjectSubmission from Django admin - Add edit functionality for project submissions in cadmin - Restructure cadmin tests from single file to tests/ folder - Add project_submission_edit view and template Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> * Add cadmin/tests to pytest testpaths Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> * Fix repository URL field name in project submissions template Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com>
1 parent a11cea3 commit f021d14

9 files changed

Lines changed: 178 additions & 7 deletions

File tree

cadmin/templates/cadmin/course_admin.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ <h2>{{ course.title }} - Admin Panel</h2>
1616
<a href="{% url 'leaderboard' course.slug %}" class="btn btn-primary">Leaderboard</a>
1717
</div>
1818

19+
<div class="mb-3">
20+
<strong>Django Admin:</strong>
21+
<a href="/admin/courses/course/{{ course.id }}/change/">
22+
<i class="fas fa-edit"></i> Edit Course
23+
</a>
24+
</div>
25+
1926
<div class="alert alert-info" role="alert">
2027
<strong>Total Enrollments:</strong> {{ total_enrollments }}
2128
</div>
@@ -43,6 +50,9 @@ <h3>Homework</h3>
4350
<tr>
4451
<td>
4552
<a href="{% url 'homework' course.slug hw.slug %}">{{ hw.title }}</a>
53+
| <a href="/admin/courses/homework/{{ hw.id }}/change/" title="Edit in Django Admin">
54+
<i class="fas fa-edit"></i>
55+
</a>
4656
</td>
4757
<td>{{ hw.due_date|date:"Y-m-d H:i" }}</td>
4858
<td>
@@ -118,6 +128,9 @@ <h3>Projects</h3>
118128
<tr>
119129
<td>
120130
<a href="{% url 'project' course.slug proj.slug %}">{{ proj.title }}</a>
131+
| <a href="/admin/courses/project/{{ proj.id }}/change/" title="Edit in Django Admin">
132+
<i class="fas fa-edit"></i>
133+
</a>
121134
</td>
122135
<td>{{ proj.submission_due_date|date:"Y-m-d H:i" }}</td>
123136
<td>{{ proj.peer_review_due_date|date:"Y-m-d H:i" }}</td>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{% extends 'base.html' %}
2+
3+
{% load custom_filters %}
4+
5+
{% block breadcrumbs %}
6+
<li><a href="{% url 'cadmin_course_list' %}">Course Admin</a></li>
7+
<li><a href="{% url 'cadmin_course' course.slug %}">{{ course.title }}</a></li>
8+
<li><a href="{% url 'cadmin_project_submissions' course.slug project.slug %}">{{ project.title }} Submissions</a></li>
9+
<li><a href="{% url 'cadmin_project_submission_edit' course.slug project.slug submission.id %}">Edit Submission</a></li>
10+
{% endblock %}
11+
12+
{% block content %}
13+
<h2>Edit Project Submission</h2>
14+
15+
<div class="mb-3">
16+
<a href="{% url 'cadmin_project_submissions' course.slug project.slug %}" class="btn btn-secondary">Back to Submissions</a>
17+
</div>
18+
19+
<div class="alert alert-info" role="alert">
20+
<strong>Student:</strong> {{ submission.student.username }} ({{ submission.student.email }})<br>
21+
<strong>Project:</strong> {{ project.title }}<br>
22+
<strong>Submitted:</strong> {{ submission.submitted_at|date:"Y-m-d H:i" }}<br>
23+
<strong>Repository:</strong> <a href="{{ submission.github_link }}" target="_blank">{{ submission.github_link }}</a>
24+
</div>
25+
26+
<form method="post">
27+
{% csrf_token %}
28+
29+
<div class="card mb-3">
30+
<div class="card-header">
31+
<h4>Project Scores</h4>
32+
</div>
33+
<div class="card-body">
34+
<div class="form-group mb-3">
35+
<label for="project_score">Project Score</label>
36+
<input type="number" class="form-control" id="project_score" name="project_score" value="{{ submission.project_score }}" required>
37+
</div>
38+
39+
<div class="form-group mb-3">
40+
<label for="project_faq_score">Project FAQ Score</label>
41+
<input type="number" class="form-control" id="project_faq_score" name="project_faq_score" value="{{ submission.project_faq_score }}" required>
42+
</div>
43+
44+
<div class="form-group mb-3">
45+
<label for="project_learning_in_public_score">Project Learning in Public Score</label>
46+
<input type="number" class="form-control" id="project_learning_in_public_score" name="project_learning_in_public_score" value="{{ submission.project_learning_in_public_score }}" required>
47+
</div>
48+
</div>
49+
</div>
50+
51+
<div class="card mb-3">
52+
<div class="card-header">
53+
<h4>Peer Review Scores</h4>
54+
</div>
55+
<div class="card-body">
56+
<div class="form-group mb-3">
57+
<label for="peer_review_score">Peer Review Score</label>
58+
<input type="number" class="form-control" id="peer_review_score" name="peer_review_score" value="{{ submission.peer_review_score }}" required>
59+
</div>
60+
61+
<div class="form-group mb-3">
62+
<label for="peer_review_learning_in_public_score">Peer Review Learning in Public Score</label>
63+
<input type="number" class="form-control" id="peer_review_learning_in_public_score" name="peer_review_learning_in_public_score" value="{{ submission.peer_review_learning_in_public_score }}" required>
64+
</div>
65+
</div>
66+
</div>
67+
68+
<div class="card mb-3">
69+
<div class="card-header">
70+
<h4>Overall Results</h4>
71+
</div>
72+
<div class="card-body">
73+
<div class="form-group mb-3">
74+
<label for="total_score">Total Score</label>
75+
<input type="number" class="form-control" id="total_score" name="total_score" value="{{ submission.total_score }}" required>
76+
</div>
77+
78+
<div class="form-check mb-3">
79+
<input type="checkbox" class="form-check-input" id="reviewed_enough_peers" name="reviewed_enough_peers" {% if submission.reviewed_enough_peers %}checked{% endif %}>
80+
<label class="form-check-label" for="reviewed_enough_peers">
81+
Reviewed Enough Peers
82+
</label>
83+
</div>
84+
85+
<div class="form-check mb-3">
86+
<input type="checkbox" class="form-check-input" id="passed" name="passed" {% if submission.passed %}checked{% endif %}>
87+
<label class="form-check-label" for="passed">
88+
Passed
89+
</label>
90+
</div>
91+
</div>
92+
</div>
93+
94+
<div class="text-center">
95+
<button type="submit" class="btn btn-primary">Save Changes</button>
96+
<a href="{% url 'cadmin_project_submissions' course.slug project.slug %}" class="btn btn-secondary">Cancel</a>
97+
</div>
98+
</form>
99+
100+
{% endblock %}

cadmin/templates/cadmin/project_submissions.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ <h2>{{ project.title }} - Submissions</h2>
4343
<th>Total Score</th>
4444
<th>Passed</th>
4545
<th>Repository URL</th>
46+
<th>Actions</th>
4647
</tr>
4748
</thead>
4849
<tbody>
@@ -85,12 +86,17 @@ <h2>{{ project.title }} - Submissions</h2>
8586
{% endif %}
8687
</td>
8788
<td>
88-
{% if submission.repository_url %}
89-
<a href="{{ submission.repository_url }}" target="_blank">View</a>
89+
{% if submission.github_link %}
90+
<a href="{{ submission.github_link }}" target="_blank">View</a>
9091
{% else %}
9192
-
9293
{% endif %}
9394
</td>
95+
<td>
96+
<a href="{% url 'cadmin_project_submission_edit' course.slug project.slug submission.id %}" class="btn btn-sm btn-primary">
97+
<i class="fas fa-edit"></i> Edit
98+
</a>
99+
</td>
94100
</tr>
95101
{% endfor %}
96102
</tbody>

cadmin/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Tests for cadmin app
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,3 @@ def test_cadmin_project_submissions_staff_allowed(self):
150150
response = self.client.get(url)
151151
self.assertEqual(response.status_code, 200)
152152
self.assertContains(response, self.project.title)
153-

cadmin/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@
3535
views.project_submissions,
3636
name="cadmin_project_submissions",
3737
),
38+
path(
39+
"<slug:course_slug>/project/<slug:project_slug>/submissions/<int:submission_id>/edit",
40+
views.project_submission_edit,
41+
name="cadmin_project_submission_edit",
42+
),
3843
]

cadmin/views.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,45 @@ def project_submissions(request, course_slug, project_slug):
250250

251251
return render(request, "cadmin/project_submissions.html", context)
252252

253+
254+
@staff_required
255+
def project_submission_edit(request, course_slug, project_slug, submission_id):
256+
"""Edit a project submission"""
257+
course = get_object_or_404(Course, slug=course_slug)
258+
project = get_object_or_404(Project, course=course, slug=project_slug)
259+
submission = get_object_or_404(
260+
ProjectSubmission,
261+
id=submission_id,
262+
project=project
263+
)
264+
265+
if request.method == "POST":
266+
# Update the submission fields
267+
try:
268+
submission.project_score = int(request.POST.get("project_score", 0))
269+
submission.project_faq_score = int(request.POST.get("project_faq_score", 0))
270+
submission.project_learning_in_public_score = int(request.POST.get("project_learning_in_public_score", 0))
271+
submission.peer_review_score = int(request.POST.get("peer_review_score", 0))
272+
submission.peer_review_learning_in_public_score = int(request.POST.get("peer_review_learning_in_public_score", 0))
273+
submission.total_score = int(request.POST.get("total_score", 0))
274+
submission.reviewed_enough_peers = request.POST.get("reviewed_enough_peers") == "on"
275+
submission.passed = request.POST.get("passed") == "on"
276+
277+
submission.save()
278+
279+
messages.success(
280+
request,
281+
f"Project submission for {submission.student.username} updated successfully",
282+
)
283+
return redirect("cadmin_project_submissions", course_slug=course_slug, project_slug=project_slug)
284+
except ValueError as e:
285+
messages.error(request, f"Error updating submission: {e}")
286+
287+
context = {
288+
"course": course,
289+
"project": project,
290+
"submission": submission,
291+
}
292+
293+
return render(request, "cadmin/project_submission_edit.html", context)
294+

courses/templates/courses/course.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ <h2>{{ course.title }}</h2>
2323
{% if is_authenticated %}
2424
<a class="btn btn-info" href="{% url 'enrollment' course.slug %}" role="button">Edit course profile</a>
2525
{% endif %}
26-
{% if user.is_staff %}
27-
<a class="btn btn-warning" href="{% url 'cadmin_course' course.slug %}" role="button">Manage course</a>
28-
{% endif %}
29-
</p>
26+
</p>
27+
{% if user.is_staff %}
28+
<p>
29+
<a href="{% url 'cadmin_course' course.slug %}">
30+
<i class="fas fa-cog"></i> Manage course (Admin only)
31+
</a>
32+
</p>
33+
{% endif %}
3034
</div>
3135

3236

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ python_files = ["test_*.py"]
4040
testpaths = [
4141
"courses/tests",
4242
"data/tests",
43+
"cadmin/tests",
4344
]

0 commit comments

Comments
 (0)