Skip to content

Commit

Permalink
🤝 Merge pull request #11 from djangocon/export-as-csv
Browse files Browse the repository at this point in the history
✨ Export as csv
  • Loading branch information
jefftriplett authored Jun 20, 2023
2 parents 8d30ff8 + cb14ed3 commit 37b9a18
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 3 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Check out our [deploy.yml](https://github.com/djangocon/grorg/blob/main/.github/

## Want to use ours?

File an issue https://github.com/djangocon/grorg/issues and we can build an issue program ID for your event.
File an issue https://github.com/djangocon/grorg/issues and we can build an issue program ID for your event.

## Kudos
## Kudos

Created by [email protected]
1 change: 1 addition & 0 deletions grants/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class urls(Urls):
questions = "{view}questions/"
applicants = "{view}applicants/"
applicants_bulk = "{view}applicants/bulk/"
applicants_csv = "{view}applicants/csv/"
scores_bulk = "{view}applicants/bulk_scores/"
resources = "{view}resources/"
users = "{view}users/"
Expand Down
53 changes: 53 additions & 0 deletions grants/views/program.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from __future__ import annotations

import collections
import csv

from django import forms
from django.db.models import Q
from django.http import Http404
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.utils import timezone
from django.views.generic import FormView, ListView, TemplateView, UpdateView, View
Expand Down Expand Up @@ -201,6 +203,57 @@ def get_context_data(self):
return context


class ProgramApplicantsCsv(ProgramMixin, ListView):
"""
Shows applications to the program.
"""

context_object_name = "applicants"

def get(self, request, *args, **kwargs):
# Work out sort
if self.request.GET.get("sort", None) == "score":
self.sort = "score"
else:
self.sort = "applied"
# Fetch applicants
# but don't let a user see their own request
applicants = list(
self.program.applicants.exclude(email=self.request.user.email)
.prefetch_related("scores")
.order_by("-applied")
)
for applicant in applicants:
applicant.has_scored = applicant.scores.filter(
user=self.request.user
).exists()
if applicant.has_scored:
applicant.average_score = applicant.average_score()
else:
applicant.average_score = -1
if self.sort == "score":
applicants.sort(key=lambda a: a.average_score, reverse=True)

# Prepare CSV response
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = 'attachment; filename="applicants.csv"'

writer = csv.writer(response)
writer.writerow(["Email", "Has Scored", "Average Score"]) # Write headers

for applicant in applicants:
writer.writerow(
[applicant.email, applicant.has_scored, applicant.average_score]
)

return response

def get_context_data(self):
context = super().get_context_data()
context["sort"] = self.sort
return context


class ProgramApplicantView(ProgramMixin, TemplateView):
"""
Shows an individual application.
Expand Down
1 change: 1 addition & 0 deletions grorg/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"<str:program>/applicants/bulk_scores/",
bulk_load.BulkLoadScores.as_view(),
),
path("<str:program>/applicants/csv/", program.ProgramApplicantsCsv.as_view()),
path(
"<str:program>/applicants/random-unscored/",
program.RandomUnscoredApplicant.as_view(),
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

[tool.pytest.ini_options]
# addopts = "--cov=. --durations=1 --nomigrations --reuse-db -vv"
addopts = "--nomigrations --reuse-db -vv"
Expand Down
1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
bumpver
django-allauth
Django<5.0
environs[django]
Expand Down
32 changes: 32 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ asgiref==3.5.2 \
--hash=sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4 \
--hash=sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424
# via django
bumpver==2023.1124 \
--hash=sha256:81ef4c969adfdb14eb3a029d46998fbb72eb7bb533073ad3468f0ecec2f4c09c \
--hash=sha256:e5632c9da189c12b16da568f0c9b5e6d7c7786a4361c150f99fb0d24fd1b7910
# via -r ./requirements.in
certifi==2022.12.7 \
--hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \
--hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18
Expand Down Expand Up @@ -155,6 +159,14 @@ charset-normalizer==3.1.0 \
--hash=sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df \
--hash=sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab
# via requests
click==8.1.3 \
--hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \
--hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48
# via bumpver
colorama==0.4.6 \
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
# via bumpver
cryptography==40.0.2 \
--hash=sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440 \
--hash=sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288 \
Expand Down Expand Up @@ -213,6 +225,14 @@ idna==3.4 \
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
# via requests
lexid==2021.1006 \
--hash=sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5 \
--hash=sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed
# via bumpver
looseversion==1.2.0 \
--hash=sha256:0b30eaca26506135c1109dbed582384f8503dee8fcfe07b85fd949f69f077977 \
--hash=sha256:c64e71c0b29030683b4ea75aee431db2d25c4e6e533590e52129f1d9e51de204
# via bumpver
marshmallow==3.16.0 \
--hash=sha256:53a1e0ee69f79e1f3e80d17393b25cfc917eda52f859e8183b4af72c3390c1f1 \
--hash=sha256:a762c1d8b2bcb0e5c8e964850d03f9f3bffd6a12b626f3c14b9d6b1841999af5
Expand All @@ -225,6 +245,10 @@ packaging==21.3 \
--hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
--hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
# via marshmallow
pathlib2==2.3.7.post1 \
--hash=sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b \
--hash=sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641
# via bumpver
psycopg2-binary==2.9.3 \
--hash=sha256:01310cf4cf26db9aea5158c217caa92d291f0500051a6469ac52166e1a16f5b7 \
--hash=sha256:083a55275f09a62b8ca4902dd11f4b33075b743cf0d360419e2051a8a5d5ff76 \
Expand Down Expand Up @@ -320,10 +344,18 @@ requests-oauthlib==1.3.1 \
--hash=sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5 \
--hash=sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a
# via django-allauth
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
# via pathlib2
sqlparse==0.4.2 \
--hash=sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae \
--hash=sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d
# via django
toml==0.10.2 \
--hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
--hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
# via bumpver
urllib3==2.0.2 \
--hash=sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc \
--hash=sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e
Expand Down
1 change: 1 addition & 0 deletions templates/program-applicants.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ <h1>Applicants</h1>
<div class="action-bar">
<a href="{{ program.urls.applicants_bulk }}" class="button boring">Bulk load applicants</a>
<a href="{{ program.urls.scores_bulk }}" class="button boring">Bulk load your scores</a>
<a href="{{ program.urls.applicants_csv }}" class="button boring">Export applications as CSV</a>
</div>
</div>
{% endblock %}

0 comments on commit 37b9a18

Please sign in to comment.