Skip to content

Commit 64a0d72

Browse files
authored
Merge pull request #7 from Tech-JI/dev
Course detail page improvements and bug fixes
2 parents 84fdc12 + ac72c5e commit 64a0d72

26 files changed

Lines changed: 1672 additions & 523 deletions

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: format-and-add
5+
name: Format code and stage changes
6+
entry: uv run scripts/pre-commit-format.py
7+
language: system
8+
pass_filenames: false
9+
always_run: true

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ format: format-backend format-frontend
3838

3939
format-backend:
4040
@echo "Formatting backend (Python) code with isort and black..."
41-
uvx isort .
42-
uvx black .
41+
uvx ruff format
4342

4443
format-frontend:
4544
@echo "Formatting frontend code with prettier..."

apps/analytics/templates/dashboard.html

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ <h1> Analytics </h1>
1212
<thead>
1313
<th>Range</th>
1414
<th><a href="/admin/auth/user/?is_active__exact=1">Users</a></th>
15-
<th>Good Votes</th>
16-
<th>Layup Votes</th>
15+
<th>Quality Ratings</th>
16+
<th>Difficulty Ratings</th>
1717
<th><a href="/admin/web/review/">Reviews</a></th>
1818
</thead>
1919
<tbody>
@@ -49,21 +49,17 @@ <h3>Vote Breakdown</h3>
4949
<table class="table">
5050
<thead>
5151
<th>Range</th>
52-
<th>Good +</th>
53-
<th>Good -</th>
54-
<th>Layup +</th>
55-
<th>Layup -</th>
52+
<th>Quality Ratings</th>
53+
<th>Difficulty Ratings</th>
5654
<th>Total Unvotes</th>
5755
</thead>
5856
<tbody>
59-
{% for c1, c2, c3, c4, c5, c6 in vote_table %}
57+
{% for c1, c2, c3, c4 in vote_table %}
6058
<tr>
6159
<th>{{ c1}}</th>
6260
<td>{{ c2 }}</td>
6361
<td>{{ c3 }}</td>
6462
<td>{{ c4 }}</td>
65-
<td>{{ c5 }}</td>
66-
<td>{{ c6 }}</td>
6763
</tr>
6864
{% endfor %}
6965
</tbody>

apps/analytics/views.py

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def home(request):
3131
.distinct()
3232
.count()
3333
)
34-
num_layup_voters = (
34+
num_difficulty_voters = (
3535
non_zero_votes.filter(category=models.Vote.CATEGORIES.DIFFICULTY)
3636
.values_list("user")
3737
.distinct()
@@ -85,16 +85,10 @@ def home(request):
8585
(
8686
"Total",
8787
models.Vote.objects.filter(
88-
value__gt=0, category=models.Vote.CATEGORIES.QUALITY
88+
value__gte=1, category=models.Vote.CATEGORIES.QUALITY
8989
).count(),
9090
models.Vote.objects.filter(
91-
value__lt=0, category=models.Vote.CATEGORIES.QUALITY
92-
).count(),
93-
models.Vote.objects.filter(
94-
value__gt=0, category=models.Vote.CATEGORIES.DIFFICULTY
95-
).count(),
96-
models.Vote.objects.filter(
97-
value__lt=0, category=models.Vote.CATEGORIES.DIFFICULTY
91+
value__gte=1, category=models.Vote.CATEGORIES.DIFFICULTY
9892
).count(),
9993
models.Vote.objects.filter(value=0).count(),
10094
)
@@ -104,22 +98,12 @@ def home(request):
10498
(
10599
name,
106100
models.Vote.objects.filter(
107-
value__gt=0,
101+
value__gte=1,
108102
category=models.Vote.CATEGORIES.QUALITY,
109103
created_at__gte=earliest_date,
110104
).count(),
111105
models.Vote.objects.filter(
112-
value__lt=0,
113-
category=models.Vote.CATEGORIES.QUALITY,
114-
created_at__gte=earliest_date,
115-
).count(),
116-
models.Vote.objects.filter(
117-
value__gt=0,
118-
category=models.Vote.CATEGORIES.DIFFICULTY,
119-
created_at__gte=earliest_date,
120-
).count(),
121-
models.Vote.objects.filter(
122-
value__lt=0,
106+
value__gte=1,
123107
category=models.Vote.CATEGORIES.DIFFICULTY,
124108
created_at__gte=earliest_date,
125109
).count(),
@@ -163,7 +147,7 @@ def home(request):
163147
"vote_table": vote_table,
164148
"num_voters": num_voters,
165149
"num_quality_voters": num_quality_voters,
166-
"num_layup_voters": num_layup_voters,
150+
"num_difficulty_voters": num_difficulty_voters,
167151
"num_reviewers": num_reviewers,
168152
"recommendations_last_updated": recommendations_last_updated,
169153
"activated_accounts": User.objects.filter(is_active=True).count(),
@@ -177,7 +161,9 @@ def home(request):
177161
@user_passes_test(lambda u: u.is_superuser)
178162
def eligible_for_recommendations(request):
179163
eligible_users_and_votes = (
180-
models.Vote.objects.filter(value=1, category=models.Vote.CATEGORIES.QUALITY)
164+
models.Vote.objects.filter(
165+
value__gte=4, category=models.Vote.CATEGORIES.QUALITY
166+
)
181167
.values_list("user")
182168
.annotate(vote_count=Count("user"))
183169
.filter(vote_count__gte=constants.REC_UPVOTE_REQ)

apps/web/admin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
DistributiveRequirement,
88
Instructor,
99
Review,
10+
ReviewVote,
1011
Student,
1112
Vote,
1213
)
@@ -17,5 +18,6 @@
1718
admin.site.register(Instructor)
1819
admin.site.register(CourseMedian)
1920
admin.site.register(Review)
21+
admin.site.register(ReviewVote)
2022
admin.site.register(Vote)
2123
admin.site.register(Student)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 5.2 on 2025-07-12 08:36
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("web", "0005_course_number_alter_course_course_code"),
9+
]
10+
11+
operations = [
12+
migrations.AlterField(
13+
model_name="course",
14+
name="difficulty_score",
15+
field=models.FloatField(default=0.0),
16+
),
17+
migrations.AlterField(
18+
model_name="course",
19+
name="quality_score",
20+
field=models.FloatField(default=0.0),
21+
),
22+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 5.2 on 2025-08-17 03:36
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("web", "0006_alter_course_difficulty_score_and_more"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="review",
14+
name="dislike_count",
15+
field=models.PositiveIntegerField(db_index=True, default=0),
16+
),
17+
migrations.AddField(
18+
model_name="review",
19+
name="kudos_count",
20+
field=models.PositiveIntegerField(db_index=True, default=0),
21+
),
22+
]
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Generated by Django 5.2 on 2025-08-18 14:32
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
dependencies = [
10+
("web", "0007_review_dislike_count_review_kudos_count"),
11+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name="ReviewVote",
17+
fields=[
18+
(
19+
"id",
20+
models.BigAutoField(
21+
auto_created=True,
22+
primary_key=True,
23+
serialize=False,
24+
verbose_name="ID",
25+
),
26+
),
27+
("is_kudos", models.BooleanField(default=True)),
28+
(
29+
"review",
30+
models.ForeignKey(
31+
on_delete=django.db.models.deletion.CASCADE,
32+
related_name="votes",
33+
to="web.review",
34+
),
35+
),
36+
(
37+
"user",
38+
models.ForeignKey(
39+
on_delete=django.db.models.deletion.CASCADE,
40+
to=settings.AUTH_USER_MODEL,
41+
),
42+
),
43+
],
44+
options={
45+
"verbose_name": "Review Vote",
46+
"verbose_name_plural": "Review Votes",
47+
"unique_together": {("review", "user")},
48+
},
49+
),
50+
]

apps/web/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
from .review import Review
77
from .student import Student
88
from .vote import Vote
9+
from .vote_for_review import ReviewVote

0 commit comments

Comments
 (0)