Skip to content

⬆️ Upgrade to Django 4.2 and update project #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,57 +1,57 @@
default_language_version:
python: python3.9

exclude: |
(?x)^(
static/.*
)$

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-json
- id: check-merge-conflict
- id: check-symlinks
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
# - repo: https://github.com/asottile/pyupgrade
# rev: v3.17.0
# hooks:
# - id: pyupgrade
# args: [--py312-plus]
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.21.0
hooks:
- id: django-upgrade
args: [--target-version, "4.2"]
- repo: https://github.com/rtts/djhtml
rev: '3.0.5'
rev: '3.0.6'
hooks:
- id: djhtml
entry: djhtml --tabwidth 4
alias: autoformat
- id: djcss
entry: djhtml --tabwidth 2
alias: autoformat
- id: djjs
alias: autoformat
- repo: https://github.com/adamchainz/django-upgrade
rev: 1.13.0
# - id: djcss
# alias: autoformat
# - id: djjs
# alias: autoformat
- repo: https://github.com/adamchainz/djade-pre-commit
rev: "1.2.0"
hooks:
- id: django-upgrade
args: [--target-version, "4.2"]
alias: autoformat
- repo: https://github.com/psf/black
rev: 23.1.0
- id: djade
args: [--target-version, "4.2"]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.14.0
hooks:
- id: black
alias: autoformat
- id: pretty-format-toml
args: [--autofix]
- repo: https://github.com/asottile/blacken-docs
rev: 1.13.0
rev: 1.18.0
hooks:
- id: blacken-docs
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.256'
hooks:
- id: ruff
alias: autoformat
args: [--fix]
# - repo: https://github.com/codespell-project/codespell
# rev: v2.2.2
# hooks:
# - id: codespell
# args: [--write-changes]
# alias: autoformat
73 changes: 37 additions & 36 deletions fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,46 @@ primary_region = "den"
processes = []

[deploy]
release_command = "python manage.py migrate --noinput"

[http_service]
auto_start_machines = true
auto_stop_machines = true
force_https = false
internal_port = 8000
min_machines_running = 0
processes = ["app"]
release_command = "python manage.py migrate --noinput"

[env]
PORT = "8000"
PORT = "8000"

[experimental]
allowed_public_ports = []
auto_rollback = true
allowed_public_ports = []
auto_rollback = true

[http_service]
auto_start_machines = true
auto_stop_machines = true
force_https = false
internal_port = 8000
min_machines_running = 0
processes = ["app"]

[[services]]
http_checks = []
internal_port = 8000
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"

[[services.ports]]
force_https = true
handlers = ["http"]
port = 80

[[services.ports]]
handlers = ["tls", "http"]
port = 443

[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
http_checks = []
internal_port = 8000
processes = ["app"]
protocol = "tcp"
script_checks = []

[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"

[[services.ports]]
force_https = true
handlers = ["http"]
port = 80

[[services.ports]]
handlers = ["tls", "http"]
port = 443

[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
14 changes: 3 additions & 11 deletions grants/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ class Meta:

def clean_type(self):
type = self.cleaned_data["type"]
if (
self.instance
and type != self.instance.type
and self.instance.answers.exists()
):
if self.instance and type != self.instance.type and self.instance.answers.exists():
raise forms.ValidationError("Cannot change once this question has answers")
return type

Expand All @@ -32,9 +28,7 @@ def __init__(self, program, *args, **kwargs):
def clean_email(self):
email = self.cleaned_data["email"]
if self.program.applicants.filter(email=email).exists():
raise forms.ValidationError(
"An application with that email address has already been submitted."
)
raise forms.ValidationError("An application with that email address has already been submitted.")
return email


Expand Down Expand Up @@ -86,7 +80,5 @@ def __init__(self, applicant, *args, **kwargs):
def clean_resource(self):
resource = self.cleaned_data["resource"]
if self.applicant.allocations.filter(resource=resource).exists():
raise forms.ValidationError(
"That resource is already allocated. Delete it if you wish to change it."
)
raise forms.ValidationError("That resource is already allocated. Delete it if you wish to change it.")
return resource
40 changes: 10 additions & 30 deletions grants/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ class Resource(models.Model):
("accomodation", "Accomodation"),
]

program = models.ForeignKey(
Program, related_name="resources", on_delete=models.CASCADE
)
program = models.ForeignKey(Program, related_name="resources", on_delete=models.CASCADE)
name = models.CharField(max_length=100)
type = models.CharField(max_length=50, choices=TYPE_CHOICES)
amount = models.PositiveIntegerField()
Expand Down Expand Up @@ -99,9 +97,7 @@ class Question(models.Model):
("integer", "Integer value"),
]

program = models.ForeignKey(
Program, related_name="questions", on_delete=models.CASCADE
)
program = models.ForeignKey(Program, related_name="questions", on_delete=models.CASCADE)
type = models.CharField(max_length=50, choices=TYPE_CHOICES)
question = models.TextField()
required = models.BooleanField(default=False)
Expand All @@ -122,9 +118,7 @@ class Applicant(models.Model):
Someone applying for a grant.
"""

program = models.ForeignKey(
Program, related_name="applicants", on_delete=models.CASCADE
)
program = models.ForeignKey(Program, related_name="applicants", on_delete=models.CASCADE)
name = models.TextField()
email = models.EmailField()

Expand Down Expand Up @@ -166,12 +160,8 @@ class Allocation(models.Model):
An allocation of some Resources to an Applicant.
"""

applicant = models.ForeignKey(
Applicant, related_name="allocations", on_delete=models.CASCADE
)
resource = models.ForeignKey(
Resource, related_name="allocations", on_delete=models.CASCADE
)
applicant = models.ForeignKey(Applicant, related_name="allocations", on_delete=models.CASCADE)
resource = models.ForeignKey(Resource, related_name="allocations", on_delete=models.CASCADE)
amount = models.PositiveIntegerField()

class Meta:
Expand All @@ -185,12 +175,8 @@ class Answer(models.Model):
An applicant's answer to a question.
"""

applicant = models.ForeignKey(
Applicant, related_name="answers", on_delete=models.CASCADE
)
question = models.ForeignKey(
Question, related_name="answers", on_delete=models.CASCADE
)
applicant = models.ForeignKey(Applicant, related_name="answers", on_delete=models.CASCADE)
question = models.ForeignKey(Question, related_name="answers", on_delete=models.CASCADE)
answer = models.TextField()

class Meta:
Expand All @@ -204,15 +190,9 @@ class Score(models.Model):
A score and optional comment on an applicant by a user.
"""

applicant = models.ForeignKey(
Applicant, related_name="scores", on_delete=models.CASCADE
)
user = models.ForeignKey(
"users.User", related_name="scores", on_delete=models.CASCADE
)
score = models.FloatField(
blank=True, null=True, help_text="From 1 (terrible) to 5 (excellent)"
)
applicant = models.ForeignKey(Applicant, related_name="scores", on_delete=models.CASCADE)
user = models.ForeignKey("users.User", related_name="scores", on_delete=models.CASCADE)
score = models.FloatField(blank=True, null=True, help_text="From 1 (terrible) to 5 (excellent)")
comment = models.TextField(
blank=True,
null=True,
Expand Down
42 changes: 10 additions & 32 deletions grants/views/bulk_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,12 @@ def post(self, request):
# If there's a CSV, load it into the database, otherwise retrieve
# the one we stored there before.
if "csv" in request.FILES:
csv_obj = UploadedCSV.objects.create(
csv=request.FILES["csv"].read().decode()
)
csv_obj = UploadedCSV.objects.create(csv=request.FILES["csv"].read().decode())
else:
csv_obj = UploadedCSV.objects.get(pk=request.POST["csv_id"])

# We always get a CSV file - parse it.
reader = csv.reader(
[x + "\n" for x in csv_obj.csv.split("\n") if len(x.strip())]
)
reader = csv.reader([x + "\n" for x in csv_obj.csv.split("\n") if len(x.strip())])

rows = list(reader)
headers = rows[0]
Expand All @@ -45,9 +41,7 @@ def post(self, request):
fields = collections.OrderedDict(
(
name,
forms.ChoiceField(
choices=column_choices, required=required, label=label
),
forms.ChoiceField(choices=column_choices, required=required, label=label),
)
for name, required, label in self.get_targets()
)
Expand All @@ -59,11 +53,7 @@ def post(self, request):
# Save and import!
errors = []
successful = 0
target_map = {
name: int(value)
for name, value in form.cleaned_data.items()
if name != "csv_id" and value
}
target_map = {name: int(value) for name, value in form.cleaned_data.items() if name != "csv_id" and value}
for i, row in enumerate(rows[1:]):
try:
with atomic():
Expand Down Expand Up @@ -120,9 +110,7 @@ def process_row(self, row, target_map):
if self.program.duplicate_emails:
applicant = None
else:
applicant = Applicant.objects.filter(
program=self.program, email=row[target_map["email"]]
).first()
applicant = Applicant.objects.filter(program=self.program, email=row[target_map["email"]]).first()
if not applicant:
applicant = Applicant(
program=self.program,
Expand All @@ -139,9 +127,7 @@ def process_row(self, row, target_map):
if target_map.get("timestamp", None):
for time_format in self.time_formats:
try:
applicant.applied = datetime.datetime.strptime(
row[target_map["timestamp"]], time_format
)
applicant.applied = datetime.datetime.strptime(row[target_map["timestamp"]], time_format)
except ValueError:
pass
applicant.save()
Expand All @@ -152,10 +138,7 @@ def process_row(self, row, target_map):
question = self.program.questions.get(pk=key.lstrip("q"))
if question.type == "boolean":
answer = str(
not any(
(raw_answer.lower().strip() == no_word)
for no_word in ("no", "false", "off", "", "0")
)
not any((raw_answer.lower().strip() == no_word) for no_word in ("no", "false", "off", "", "0"))
)
elif question.type == "integer":
if not raw_answer.strip():
Expand All @@ -165,14 +148,11 @@ def process_row(self, row, target_map):
answer = str(int(raw_answer.strip()))
except ValueError:
raise ValueError(
"Invalid integer value for question %s: %s"
% (question.question, raw_answer)
"Invalid integer value for question %s: %s" % (question.question, raw_answer)
)
else:
answer = raw_answer
answer_obj = Answer.objects.filter(
applicant=applicant, question=question
).first()
answer_obj = Answer.objects.filter(applicant=applicant, question=question).first()
if not answer_obj:
answer_obj = Answer(
applicant=applicant,
Expand All @@ -199,9 +179,7 @@ def get_targets(self):
def process_row(self, row, target_map):
applicant = Applicant.objects.get(email=row[target_map["email"]])

score = Score.objects.get_or_create(
applicant=applicant, user=self.request.user
)[0]
score = Score.objects.get_or_create(applicant=applicant, user=self.request.user)[0]
score_value = row[target_map["score"]]
try:
score.score = float(score_value)
Expand Down
Loading
Loading