style: reformat

This commit is contained in:
Ethan Nguyen 2021-04-19 18:50:03 -04:00
parent 9ad55a731d
commit 337d3e2f35
No known key found for this signature in database
GPG Key ID: B4CA5339AF911920
31 changed files with 671 additions and 223 deletions

35
scripts/format.sh Executable file
View File

@ -0,0 +1,35 @@
#!/bin/bash
# MIT License
#
# Copyright (c) 2017 The TJ Director Development Team
# Copyright (c) 2019 The TJHSST Director 4.0 Development Team & Contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
cd "$(dirname -- "$(dirname -- "$(readlink -f "$0")")")"
for cmd in black autopep8 isort; do
if [[ ! -x "$(which "$cmd")" ]]; then
echo "Could not find $cmd. Please make sure that black, autopep8, and isort are all installed."
exit 1
fi
done
black tjdests && autopep8 --in-place --recursive tjdests && isort tjdests

View File

@ -12,4 +12,4 @@ def require_accept_tos(func):
return func(request, *args, **kwargs)
return wrapper
return wrapper

View File

@ -1,47 +1,69 @@
from django import forms
from django.contrib.auth import password_validation
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms
from django.contrib.auth import password_validation
class TOSForm(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.form_method = "post"
self.helper.add_input(Submit('submit', 'Submit'))
self.helper.add_input(Submit("submit", "Submit"))
accept_tos = forms.BooleanField(required=True, label="I accept the terms of the GNU Affero General Public License as displayed above,"
" and I understand that the terms that provide this software WITHOUT ANY WARRANTY;"
" without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.")
accept_tos = forms.BooleanField(
required=True,
label="I accept the terms of the GNU Affero General Public License as displayed above,"
" and I understand that the terms that provide this software WITHOUT ANY WARRANTY;"
" without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
)
password = forms.CharField(widget=forms.PasswordInput, required=True)
password_confirm = forms.CharField(widget=forms.PasswordInput, required=True)
password_confirm = forms.CharField(
widget=forms.PasswordInput, required=True)
understand_no_reset = forms.BooleanField(required=True, label="I understand that there is NO PASSWORD RESET functionality once I no longer have access to Ion.")
understand_no_reset = forms.BooleanField(
required=True,
label="I understand that there is NO PASSWORD RESET functionality once I no longer have access to Ion.",
)
def clean(self):
cleaned_data = super(TOSForm, self).clean()
password1 = cleaned_data.get('password')
password2 = cleaned_data.get('password_confirm')
password1 = cleaned_data.get("password")
password2 = cleaned_data.get("password_confirm")
if password1 and password1 != password2:
raise forms.ValidationError({"password": ["The two passwords do not match.",]})
raise forms.ValidationError(
{
"password": [
"The two passwords do not match.",
]
}
)
# Validate checkboxes checked
accept_tos = cleaned_data.get("accept_tos")
understand_no_reset = cleaned_data.get("understand_no_reset")
if not accept_tos:
raise forms.ValidationError({"accept_tos": ["You must accept the license terms to continue.",]})
raise forms.ValidationError(
{
"accept_tos": [
"You must accept the license terms to continue.",
]
}
)
if not understand_no_reset:
raise forms.ValidationError({"understand_no_reset": ["You must acknowledge that there is no password reset to continue.",]})
raise forms.ValidationError(
{
"understand_no_reset": [
"You must acknowledge that there is no password reset to continue.",
]
}
)
# Validate the password for complexity, etc.
validators = password_validation.get_default_password_validators()
password_validation.validate_password(password1, None, validators)

View File

@ -2,45 +2,117 @@
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
dependencies = []
operations = [
migrations.CreateModel(
name='User',
name="User",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('accepted_terms', models.BooleanField(default=False)),
('graduation_year', models.PositiveSmallIntegerField(null=True)),
('is_senior', models.BooleanField(default=False)),
('publish_data', models.BooleanField(default=False, verbose_name='Publish my data')),
('biography', models.TextField(blank=True)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("password", models.CharField(
max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=150, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
("accepted_terms", models.BooleanField(default=False)),
("graduation_year", models.PositiveSmallIntegerField(null=True)),
("is_senior", models.BooleanField(default=False)),
(
"publish_data",
models.BooleanField(
default=False, verbose_name="Publish my data"),
),
("biography", models.TextField(blank=True)),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
("objects", django.contrib.auth.models.UserManager()),
],
),
]

View File

@ -1,7 +1,7 @@
# Generated by Django 3.2 on 2021-04-19 15:03
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
@ -9,25 +9,46 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('authentication', '0001_initial'),
('destinations', '0001_initial'),
("auth", "0012_alter_user_first_name_max_length"),
("authentication", "0001_initial"),
("destinations", "0001_initial"),
]
operations = [
migrations.AddField(
model_name='user',
name='attending_decision',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='attending_college', to='destinations.decision', verbose_name='College attending'),
model_name="user",
name="attending_decision",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="attending_college",
to="destinations.decision",
verbose_name="College attending",
),
),
migrations.AddField(
model_name='user',
name='groups',
field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups'),
model_name="user",
name="groups",
field=models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.Group",
verbose_name="groups",
),
),
migrations.AddField(
model_name='user',
name='user_permissions',
field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'),
model_name="user",
name="user_permissions",
field=models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.Permission",
verbose_name="user permissions",
),
),
]

View File

@ -6,13 +6,17 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0002_initial'),
("authentication", "0002_initial"),
]
operations = [
migrations.AlterField(
model_name='user',
name='publish_data',
field=models.BooleanField(default=False, help_text='Unless this is set, your data will not appear publicly.', verbose_name='Publish my data'),
model_name="user",
name="publish_data",
field=models.BooleanField(
default=False,
help_text="Unless this is set, your data will not appear publicly.",
verbose_name="Publish my data",
),
),
]

View File

@ -1,25 +1,33 @@
# Generated by Django 3.2 on 2021-04-19 17:13
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('destinations', '0005_alter_decision_admission_status'),
('authentication', '0003_alter_user_publish_data'),
("destinations", "0005_alter_decision_admission_status"),
("authentication", "0003_alter_user_publish_data"),
]
operations = [
migrations.AddField(
model_name='user',
name='is_student',
model_name="user",
name="is_student",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='user',
name='attending_decision',
field=models.ForeignKey(blank=True, help_text="Can't see your college? Make sure you've added a decision with an admit status.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='attending_college', to='destinations.decision', verbose_name='College attending'),
model_name="user",
name="attending_decision",
field=models.ForeignKey(
blank=True,
help_text="Can't see your college? Make sure you've added a decision with an admit status.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="attending_college",
to="destinations.decision",
verbose_name="College attending",
),
),
]

View File

@ -1,8 +1,9 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db import models
from ..destinations.models import Decision, TestScore
class User(AbstractUser):
accepted_terms = models.BooleanField(default=False)
graduation_year = models.PositiveSmallIntegerField(null=True)
@ -11,12 +12,22 @@ class User(AbstractUser):
is_student = models.BooleanField(default=False)
# The rest are used only if a senior
publish_data = models.BooleanField(default=False, verbose_name="Publish my data", help_text="Unless this is set, your data will not appear publicly.")
publish_data = models.BooleanField(
default=False,
verbose_name="Publish my data",
help_text="Unless this is set, your data will not appear publicly.",
)
biography = models.TextField(blank=True)
attending_decision = models.ForeignKey(Decision, on_delete=models.SET_NULL, null=True, blank=True,
verbose_name="College attending", related_name="attending_college",
help_text="Can't see your college? Make sure you've added a decision with an admit status.")
attending_decision = models.ForeignKey(
Decision,
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name="College attending",
related_name="attending_college",
help_text="Can't see your college? Make sure you've added a decision with an admit status.",
)
def __str__(self):
return f"{self.first_name} {self.last_name}"

View File

@ -7,14 +7,16 @@ class IonOauth2(BaseOAuth2):
AUTHORIZATION_URL = "https://ion.tjhsst.edu/oauth/authorize"
ACCESS_TOKEN_URL = "https://ion.tjhsst.edu/oauth/token"
ACCESS_TOKEN_METHOD = "POST"
EXTRA_DATA = [("refresh_token", "refresh_token", True), ("expires_in", "expires")]
EXTRA_DATA = [("refresh_token", "refresh_token", True),
("expires_in", "expires")]
def get_scope(self):
return ["read"]
def get_user_details(self, response):
profile = self.get_json(
"https://ion.tjhsst.edu/api/profile", params={"access_token": response["access_token"]}
"https://ion.tjhsst.edu/api/profile",
params={"access_token": response["access_token"]},
)
# fields used to populate/update User model
@ -31,8 +33,8 @@ class IonOauth2(BaseOAuth2):
"is_student": profile["is_student"],
"is_teacher": profile["is_teacher"],
"graduation_year": profile["graduation_year"],
"is_senior": int(profile["graduation_year"]) == settings.SENIOR_GRAD_YEAR
"is_senior": int(profile["graduation_year"]) == settings.SENIOR_GRAD_YEAR,
}
def get_user_id(self, details, response):
return details["id"]
return details["id"]

View File

@ -1,5 +1,6 @@
from django.contrib.auth.views import LogoutView
from django.urls import path
from . import views
app_name = "authentication"
@ -9,4 +10,4 @@ urlpatterns = [
path("login", views.LoginViewCustom.as_view(), name="login"),
path("logout", LogoutView.as_view(), name="logout"),
path("tos", views.accept_tos_view, name="tos"),
]
]

View File

@ -1,9 +1,9 @@
from django.contrib import messages
from django.contrib.auth import login, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import LoginView
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render, redirect
from django.shortcuts import redirect, render
from django.urls import reverse
from tjdests.apps.authentication.decorators import require_accept_tos
@ -13,6 +13,7 @@ from tjdests.apps.authentication.forms import TOSForm
def index_view(request: HttpRequest) -> HttpResponse:
return render(request, "authentication/index.html")
@login_required
def accept_tos_view(request: HttpRequest) -> HttpResponse:
assert request.user.is_authenticated
@ -33,7 +34,11 @@ def accept_tos_view(request: HttpRequest) -> HttpResponse:
request.user.set_password(form.cleaned_data.get("password"))
request.user.save()
login(request, request.user, backend='django.contrib.auth.backends.ModelBackend')
login(
request,
request.user,
backend="django.contrib.auth.backends.ModelBackend",
)
messages.success(request, "You have logged in.")
@ -45,6 +50,6 @@ def accept_tos_view(request: HttpRequest) -> HttpResponse:
return render(request, "authentication/accept_tos.html", context=context)
class LoginViewCustom(LoginView):
template_name = "authentication/login.html"

View File

@ -1,4 +1,5 @@
from django.conf import settings
def settings_renderer(request):
return {"settings": settings}

View File

@ -1,6 +1,6 @@
from django.contrib import admin
from .models import College, TestScore, Decision
from .models import College, Decision, TestScore
admin.site.register(College)
admin.site.register(TestScore)

View File

@ -5,6 +5,7 @@ from django.core.management.base import BaseCommand
from ...models import College
class Command(BaseCommand):
help = "Imports a CSV of CEEB codes as colleges"
@ -20,9 +21,21 @@ class Command(BaseCommand):
reader = csv.DictReader(file)
for line in reader:
result = College.objects.update_or_create(ceeb_code=line["CEEB"], defaults={"name": line["College Name"], "location": f"{line['City']}, {line['State']}"})
result = College.objects.update_or_create(
ceeb_code=line["CEEB"],
defaults={
"name": line["College Name"],
"location": f"{line['City']}, {line['State']}",
},
)
if result[1]:
self.stdout.write(f"Added university {result[0].name}.", style_func=self.style.SUCCESS)
self.stdout.write(
f"Added university {result[0].name}.",
style_func=self.style.SUCCESS,
)
else:
self.stdout.write(f"Did not update university {result[0].name}.", style_func=self.style.WARNING)
self.stdout.write(
f"Did not update university {result[0].name}.",
style_func=self.style.WARNING,
)

View File

@ -1,8 +1,8 @@
# Generated by Django 3.2 on 2021-04-19 15:03
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
@ -15,30 +15,165 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
name='College',
name="College",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ceeb_code', models.PositiveSmallIntegerField(verbose_name='CEEB Code')),
('name', models.CharField(max_length=250)),
('location', models.CharField(max_length=250)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"ceeb_code",
models.PositiveSmallIntegerField(verbose_name="CEEB Code"),
),
("name", models.CharField(max_length=250)),
("location", models.CharField(max_length=250)),
],
),
migrations.CreateModel(
name='TestScore',
name="TestScore",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('exam_type', models.CharField(choices=[('ACT_ENGL', 'ACT English (Grammar)'), ('ACT_MATH', 'ACT Math'), ('ACT_READ', 'ACT Reading'), ('ACT_SCI', 'ACT Science'), ('ACT_COMP', 'ACT Composite'), ('SAT_EBRW', 'SAT Verbal'), ('SAT_MATH', 'SAT Math'), ('SAT_TOTAL', 'SAT Total'), ('SAT2_MATH1', 'SAT Subject Test Math 1'), ('SAT2_MATH2', 'SAT Subject Test Math 2'), ('SAT2_BIO', 'SAT Subject Test Biology'), ('SAT2_CHEM', 'SAT Subject Test Chemistry'), ('SAT2_PHYS', 'SAT Subject Test Physics'), ('SAT2_ENGL', 'SAT Subject Test English'), ('SAT2_USH', 'SAT Subject Test U.S. History'), ('SAT2_WH', 'SAT Subject Test World History'), ('SAT2_ES', 'SAT Subject Test Spanish'), ('SAT2_ESL', 'SAT Subject Test Spanish with Listening'), ('SAT2_FR', 'SAT Subject Test French'), ('SAT2_FRL', 'SAT Subject Test French with Listening'), ('SAT2_ZHL', 'SAT Subject Test Chinese with Listening'), ('SAT2_IT', 'SAT Subject Test Italian'), ('SAT2_DE', 'SAT Subject Test German'), ('SAT2_DEL', 'SAT Subject Test German with Listening'), ('SAT2_HE', 'SAT Subject Test Modern Hebrew'), ('SAT2_LA', 'SAT Subject Test Latin'), ('SAT2_JAL', 'SAT Subject Test Japanese with Listening'), ('SAT2_KOL', 'SAT Subject Test Korean with Listening'), ('AP_RSRCH', 'AP Research'), ('AP_SMNR', 'AP Seminar'), ('AP_ART2D', 'AP Art and Design: 2-D Design'), ('AP_ART3D', 'AP Art and Design: 3-D Design'), ('AP_ARTDRAW', 'AP Art and Design: Drawing'), ('AP_ARTHIST', 'AP Art History'), ('AP_BIO', 'AP Biology'), ('AP_CALCAB', 'AP Calculus AB'), ('AP_CALCBC', 'AP Calculus BC'), ('AP_CHEM', 'AP Chemistry'), ('AP_ZHLANG', 'AP Chinese Language and Culture'), ('AP_CSA', 'AP Computer Science A'), ('AP_CSP', 'AP Computer Science Principles'), ('AP_ENLANG', 'AP English Language and Composition'), ('AP_ENLIT', 'AP English Literature and Composition'), ('AP_ENVSCI', 'AP Environmental Science'), ('AP_EUROHIST', 'AP European History'), ('AP_FRLANG', 'AP French Language and Culture'), ('AP_DELANG', 'AP German Language and Culture'), ('AP_GOVCOMP', 'AP Comparative Government and Politics'), ('AP_GOVUS', 'AP U.S. Government and Politics'), ('AP_HUG', 'AP Human Geography'), ('AP_ITLANG', 'AP Italian Language and Culture'), ('AP_JALANG', 'AP Japanese Language and Culture'), ('AP_LATIN', 'AP Latin'), ('AP_MACRO', 'AP Macroeconomics'), ('AP_MICRO', 'AP Microeconomics'), ('AP_MUSTHRY', 'AP Music Theory'), ('AP_PHYSICS1', 'AP Physics 1: Algebra-Based'), ('AP_PHYSICS2', 'AP Physics 2: Algebra-Based'), ('AP_PHYSICSCEM', 'AP Physics C: Electricity and Magnetism'), ('AP_PHYSICSCM', 'AP Physics C: Mechanics'), ('AP_PSYCH', 'AP Psychology'), ('AP_ESLANG', 'AP Spanish Language and Culture'), ('AP_ESLIT', 'AP Spanish Literature and Culture'), ('AP_STAT', 'AP Statistics'), ('AP_USH', 'AP US History'), ('AP_WHM', 'AP World History: Modern')], max_length=20)),
('exam_score', models.PositiveSmallIntegerField()),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"exam_type",
models.CharField(
choices=[
("ACT_ENGL", "ACT English (Grammar)"),
("ACT_MATH", "ACT Math"),
("ACT_READ", "ACT Reading"),
("ACT_SCI", "ACT Science"),
("ACT_COMP", "ACT Composite"),
("SAT_EBRW", "SAT Verbal"),
("SAT_MATH", "SAT Math"),
("SAT_TOTAL", "SAT Total"),
("SAT2_MATH1", "SAT Subject Test Math 1"),
("SAT2_MATH2", "SAT Subject Test Math 2"),
("SAT2_BIO", "SAT Subject Test Biology"),
("SAT2_CHEM", "SAT Subject Test Chemistry"),
("SAT2_PHYS", "SAT Subject Test Physics"),
("SAT2_ENGL", "SAT Subject Test English"),
("SAT2_USH", "SAT Subject Test U.S. History"),
("SAT2_WH", "SAT Subject Test World History"),
("SAT2_ES", "SAT Subject Test Spanish"),
("SAT2_ESL", "SAT Subject Test Spanish with Listening"),
("SAT2_FR", "SAT Subject Test French"),
("SAT2_FRL", "SAT Subject Test French with Listening"),
("SAT2_ZHL", "SAT Subject Test Chinese with Listening"),
("SAT2_IT", "SAT Subject Test Italian"),
("SAT2_DE", "SAT Subject Test German"),
("SAT2_DEL", "SAT Subject Test German with Listening"),
("SAT2_HE", "SAT Subject Test Modern Hebrew"),
("SAT2_LA", "SAT Subject Test Latin"),
("SAT2_JAL", "SAT Subject Test Japanese with Listening"),
("SAT2_KOL", "SAT Subject Test Korean with Listening"),
("AP_RSRCH", "AP Research"),
("AP_SMNR", "AP Seminar"),
("AP_ART2D", "AP Art and Design: 2-D Design"),
("AP_ART3D", "AP Art and Design: 3-D Design"),
("AP_ARTDRAW", "AP Art and Design: Drawing"),
("AP_ARTHIST", "AP Art History"),
("AP_BIO", "AP Biology"),
("AP_CALCAB", "AP Calculus AB"),
("AP_CALCBC", "AP Calculus BC"),
("AP_CHEM", "AP Chemistry"),
("AP_ZHLANG", "AP Chinese Language and Culture"),
("AP_CSA", "AP Computer Science A"),
("AP_CSP", "AP Computer Science Principles"),
("AP_ENLANG", "AP English Language and Composition"),
("AP_ENLIT", "AP English Literature and Composition"),
("AP_ENVSCI", "AP Environmental Science"),
("AP_EUROHIST", "AP European History"),
("AP_FRLANG", "AP French Language and Culture"),
("AP_DELANG", "AP German Language and Culture"),
("AP_GOVCOMP", "AP Comparative Government and Politics"),
("AP_GOVUS", "AP U.S. Government and Politics"),
("AP_HUG", "AP Human Geography"),
("AP_ITLANG", "AP Italian Language and Culture"),
("AP_JALANG", "AP Japanese Language and Culture"),
("AP_LATIN", "AP Latin"),
("AP_MACRO", "AP Macroeconomics"),
("AP_MICRO", "AP Microeconomics"),
("AP_MUSTHRY", "AP Music Theory"),
("AP_PHYSICS1", "AP Physics 1: Algebra-Based"),
("AP_PHYSICS2", "AP Physics 2: Algebra-Based"),
(
"AP_PHYSICSCEM",
"AP Physics C: Electricity and Magnetism",
),
("AP_PHYSICSCM", "AP Physics C: Mechanics"),
("AP_PSYCH", "AP Psychology"),
("AP_ESLANG", "AP Spanish Language and Culture"),
("AP_ESLIT", "AP Spanish Literature and Culture"),
("AP_STAT", "AP Statistics"),
("AP_USH", "AP US History"),
("AP_WHM", "AP World History: Modern"),
],
max_length=20,
),
),
("exam_score", models.PositiveSmallIntegerField()),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name='Decision',
name="Decision",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('decision_type', models.CharField(choices=[('ED', 'Early Decision'), ('ED2', 'Early Decision 2'), ('EA', 'Early Action'), ('EA2', 'Early Action 2'), ('RD', 'Regular Decision'), ('RL', 'Rolling')], max_length=20, null=True)),
('college', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='destinations.college')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"decision_type",
models.CharField(
choices=[
("ED", "Early Decision"),
("ED2", "Early Decision 2"),
("EA", "Early Action"),
("EA2", "Early Action 2"),
("RD", "Regular Decision"),
("RL", "Rolling"),
],
max_length=20,
null=True,
),
),
(
"college",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="destinations.college",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('destinations', '0001_initial'),
("destinations", "0001_initial"),
]
operations = [
migrations.AddField(
model_name='decision',
name='admitted',
model_name="decision",
name="admitted",
field=models.BooleanField(default=False),
),
]

View File

@ -6,13 +6,26 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('destinations', '0002_decision_admitted'),
("destinations", "0002_decision_admitted"),
]
operations = [
migrations.AlterField(
model_name='decision',
name='admitted',
field=models.CharField(choices=[('ADMIT', 'Admitted'), ('WAITLIST', 'Waitlisted'), ('WAITLIST_ADMIT', 'Waitlist-Admitted'), ('WAITLIST_DENY', 'Waitlist-Denied'), ('DEFER', 'Deferred'), ('DEFER_ADMIT', 'Deferred-Admitted'), ('DEFER_DENY', 'Deferred-Denied'), ('DENY', 'Denied')], default='DENY', max_length=20),
model_name="decision",
name="admitted",
field=models.CharField(
choices=[
("ADMIT", "Admitted"),
("WAITLIST", "Waitlisted"),
("WAITLIST_ADMIT", "Waitlist-Admitted"),
("WAITLIST_DENY", "Waitlist-Denied"),
("DEFER", "Deferred"),
("DEFER_ADMIT", "Deferred-Admitted"),
("DEFER_DENY", "Deferred-Denied"),
("DENY", "Denied"),
],
default="DENY",
max_length=20,
),
),
]

View File

@ -6,13 +6,13 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('destinations', '0003_alter_decision_admitted'),
("destinations", "0003_alter_decision_admitted"),
]
operations = [
migrations.RenameField(
model_name='decision',
old_name='admitted',
new_name='admission_status',
model_name="decision",
old_name="admitted",
new_name="admission_status",
),
]

View File

@ -6,13 +6,25 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('destinations', '0004_rename_admitted_decision_admission_status'),
("destinations", "0004_rename_admitted_decision_admission_status"),
]
operations = [
migrations.AlterField(
model_name='decision',
name='admission_status',
field=models.CharField(choices=[('ADMIT', 'Admitted'), ('WAITLIST', 'Waitlisted'), ('WAITLIST_ADMIT', 'Waitlist-Admitted'), ('WAITLIST_DENY', 'Waitlist-Denied'), ('DEFER', 'Deferred'), ('DEFER_ADMIT', 'Deferred-Admitted'), ('DEFER_DENY', 'Deferred-Denied'), ('DENY', 'Denied')], max_length=20),
model_name="decision",
name="admission_status",
field=models.CharField(
choices=[
("ADMIT", "Admitted"),
("WAITLIST", "Waitlisted"),
("WAITLIST_ADMIT", "Waitlist-Admitted"),
("WAITLIST_DENY", "Waitlist-Denied"),
("DEFER", "Deferred"),
("DEFER_ADMIT", "Deferred-Admitted"),
("DEFER_DENY", "Deferred-Denied"),
("DENY", "Denied"),
],
max_length=20,
),
),
]

View File

@ -6,13 +6,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('destinations', '0005_alter_decision_admission_status'),
("destinations", "0005_alter_decision_admission_status"),
]
operations = [
migrations.AlterField(
model_name='college',
name='ceeb_code',
field=models.CharField(max_length=10, verbose_name='CEEB Code'),
model_name="college",
name="ceeb_code",
field=models.CharField(max_length=10, verbose_name="CEEB Code"),
),
]

View File

@ -4,7 +4,8 @@ from django.db import models
class College(models.Model):
"""Represents a college."""
ceeb_code = models.CharField(max_length=10, null=False, verbose_name="CEEB Code")
ceeb_code = models.CharField(
max_length=10, null=False, verbose_name="CEEB Code")
name = models.CharField(max_length=250, null=False, blank=False)
location = models.CharField(max_length=250, null=False, blank=False)
@ -33,7 +34,9 @@ class Decision(models.Model):
user = models.ForeignKey("authentication.User", on_delete=models.CASCADE)
decision_type = models.CharField(max_length=20, choices=DECISION_TYPE_CHOICES, null=True)
decision_type = models.CharField(
max_length=20, choices=DECISION_TYPE_CHOICES, null=True
)
ADMIT = "ADMIT"
WAITLIST_ADMIT = "WAITLIST_ADMIT"
@ -55,7 +58,8 @@ class Decision(models.Model):
(DENY, "Denied"),
]
admission_status = models.CharField(max_length=20, choices=ADMIT_TYPE_CHOICES)
admission_status = models.CharField(
max_length=20, choices=ADMIT_TYPE_CHOICES)
college = models.ForeignKey(College, on_delete=models.CASCADE)
def __str__(self):

View File

@ -1,4 +1,5 @@
from django.urls import path
from . import views
app_name = "destinations"
@ -6,4 +7,4 @@ app_name = "destinations"
urlpatterns = [
path("", views.StudentDestinationListView.as_view(), name="students"),
path("colleges", views.CollegeDestinationListView.as_view(), name="colleges"),
]
]

View File

@ -1,10 +1,10 @@
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.db.models import Count, Q
from django.shortcuts import get_object_or_404
from django.views.generic import ListView
from .models import College, Decision
from ..authentication.models import User
from .models import College, Decision
class StudentDestinationListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
@ -12,7 +12,9 @@ class StudentDestinationListView(LoginRequiredMixin, UserPassesTestMixin, ListVi
paginate_by = 20
def get_queryset(self):
queryset = User.objects.filter(publish_data=True, is_senior=True).order_by("last_name", "first_name")
queryset = User.objects.filter(publish_data=True, is_senior=True).order_by(
"last_name", "first_name"
)
college_id = self.request.GET.get("college", None)
if college_id is not None:
@ -22,7 +24,8 @@ class StudentDestinationListView(LoginRequiredMixin, UserPassesTestMixin, ListVi
return queryset
def get_context_data(self, *, object_list=None, **kwargs):
context = super(StudentDestinationListView, self).get_context_data(**kwargs)
context = super(StudentDestinationListView,
self).get_context_data(**kwargs)
college_id = self.request.GET.get("college", None)
if college_id is not None:
@ -39,31 +42,71 @@ class StudentDestinationListView(LoginRequiredMixin, UserPassesTestMixin, ListVi
class CollegeDestinationListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
model = College
paginate_by = 20
queryset = College.objects.annotate(count_decisions=Count("decision", filter=Q(decision__user__publish_data=True)),
count_admit=Count("decision",
filter=Q(decision__admission_status=Decision.ADMIT,
decision__user__publish_data=True)),
count_waitlist=Count("decision",
filter=Q(decision__admission_status=Decision.WAITLIST,
decision__user__publish_data=True)),
count_waitlist_admit=Count("decision", filter=Q(
decision__admission_status=Decision.WAITLIST_ADMIT,
decision__user__publish_data=True)),
count_waitlist_deny=Count("decision", filter=Q(
decision__admission_status=Decision.WAITLIST_DENY,
decision__user__publish_data=True)),
count_defer=Count("decision",
filter=Q(decision__admission_status=Decision.DEFER,
decision__user__publish_data=True)),
count_defer_admit=Count("decision", filter=Q(
decision__admission_status=Decision.DEFER_ADMIT,
decision__user__publish_data=True)),
count_defer_deny=Count("decision",
filter=Q(decision__admission_status=Decision.DEFER_DENY,
decision__user__publish_data=True)),
count_deny=Count("decision", filter=Q(decision__admission_status=Decision.DENY,
decision__user__publish_data=True)),
).filter(count_decisions__gte=1).order_by("name")
queryset = (
College.objects.annotate(
count_decisions=Count(
"decision", filter=Q(decision__user__publish_data=True)
),
count_admit=Count(
"decision",
filter=Q(
decision__admission_status=Decision.ADMIT,
decision__user__publish_data=True,
),
),
count_waitlist=Count(
"decision",
filter=Q(
decision__admission_status=Decision.WAITLIST,
decision__user__publish_data=True,
),
),
count_waitlist_admit=Count(
"decision",
filter=Q(
decision__admission_status=Decision.WAITLIST_ADMIT,
decision__user__publish_data=True,
),
),
count_waitlist_deny=Count(
"decision",
filter=Q(
decision__admission_status=Decision.WAITLIST_DENY,
decision__user__publish_data=True,
),
),
count_defer=Count(
"decision",
filter=Q(
decision__admission_status=Decision.DEFER,
decision__user__publish_data=True,
),
),
count_defer_admit=Count(
"decision",
filter=Q(
decision__admission_status=Decision.DEFER_ADMIT,
decision__user__publish_data=True,
),
),
count_defer_deny=Count(
"decision",
filter=Q(
decision__admission_status=Decision.DEFER_DENY,
decision__user__publish_data=True,
),
),
count_deny=Count(
"decision",
filter=Q(
decision__admission_status=Decision.DENY,
decision__user__publish_data=True,
),
),
)
.filter(count_decisions__gte=1)
.order_by("name")
)
def test_func(self):
return self.request.user.accepted_terms

View File

@ -1,10 +1,8 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms
from tjdests.apps.authentication.models import User
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from tjdests.apps.destinations.models import Decision
@ -12,16 +10,24 @@ class ProfilePublishForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.form_method = "post"
self.helper.add_input(Submit('submit', 'Submit'))
self.helper.add_input(Submit("submit", "Submit"))
self.fields["attending_decision"].queryset = Decision.objects.filter(user=self.instance, admission_status__in=[Decision.ADMIT, Decision.WAITLIST_ADMIT, Decision.DEFER_ADMIT])
self.fields["attending_decision"].queryset = Decision.objects.filter(
user=self.instance,
admission_status__in=[
Decision.ADMIT,
Decision.WAITLIST_ADMIT,
Decision.DEFER_ADMIT,
],
)
class Meta:
model = User
fields = ["publish_data", "biography", "attending_decision"]
class DecisionForm(forms.ModelForm):
class Meta:
model = Decision

View File

@ -1,4 +1,5 @@
from django.urls import path
from . import views
app_name = "profile"
@ -6,9 +7,25 @@ app_name = "profile"
urlpatterns = [
path("", views.profile_view, name="index"),
path("testscore/add", views.TestScoreCreateView.as_view(), name="testscores_add"),
path("testscore/edit/<int:pk>", views.TestScoreUpdateView.as_view(), name="testscores_edit"),
path("testscore/delete/<int:pk>", views.TestScoreDeleteView.as_view(), name="testscores_delete"),
path(
"testscore/edit/<int:pk>",
views.TestScoreUpdateView.as_view(),
name="testscores_edit",
),
path(
"testscore/delete/<int:pk>",
views.TestScoreDeleteView.as_view(),
name="testscores_delete",
),
path("decision/add", views.DecisionCreateView.as_view(), name="decision_add"),
path("decision/edit/<int:pk>", views.DecisionUpdateView.as_view(), name="decision_edit"),
path("decision/delete/<int:pk>", views.DecisionDeleteView.as_view(), name="decision_delete"),
]
path(
"decision/edit/<int:pk>",
views.DecisionUpdateView.as_view(),
name="decision_edit",
),
path(
"decision/delete/<int:pk>",
views.DecisionDeleteView.as_view(),
name="decision_delete",
),
]

View File

@ -1,16 +1,16 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.http import HttpRequest
from django.shortcuts import render
from django.urls import reverse
from django.views.generic import CreateView, UpdateView, DeleteView
from django.views.generic import CreateView, DeleteView, UpdateView
from tjdests.apps.authentication.decorators import require_accept_tos
from tjdests.apps.destinations.models import TestScore, Decision
from tjdests.apps.destinations.models import Decision, TestScore
from .forms import ProfilePublishForm, DecisionForm
from .forms import DecisionForm, ProfilePublishForm
@login_required
@ -29,12 +29,18 @@ def profile_view(request: HttpRequest):
else:
profile_form = ProfilePublishForm(instance=request.user)
context = {"test_scores_list": test_scores, "decisions_list": decisions, "profile_form": profile_form}
context = {
"test_scores_list": test_scores,
"decisions_list": decisions,
"profile_form": profile_form,
}
return render(request, "profile/profile.html", context=context)
class TestScoreCreateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, CreateView):
class TestScoreCreateView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, CreateView
):
model = TestScore
fields = ["exam_type", "exam_score"]
template_name = "profile/testscore_form.html"
@ -51,7 +57,9 @@ class TestScoreCreateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTes
return reverse("profile:index")
class TestScoreUpdateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView):
class TestScoreUpdateView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView
):
model = TestScore
fields = ["exam_type", "exam_score"]
template_name = "profile/testscore_form.html"
@ -72,7 +80,9 @@ class TestScoreUpdateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTes
return reverse("profile:index")
class TestScoreDeleteView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, DeleteView):
class TestScoreDeleteView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, DeleteView
):
model = TestScore
template_name = "profile/testscore_delete.html"
success_message = "Test score deleted successfully."
@ -87,7 +97,10 @@ class TestScoreDeleteView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTes
def get_success_url(self):
return reverse("profile:index")
class DecisionCreateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, CreateView):
class DecisionCreateView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, CreateView
):
model = Decision
fields = ["college", "decision_type", "admission_status"]
template_name = "profile/decision_form.html"
@ -104,7 +117,9 @@ class DecisionCreateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTest
return reverse("profile:index")
class DecisionUpdateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView):
class DecisionUpdateView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, UpdateView
):
model = Decision
fields = ["college", "decision_type", "admission_status"]
template_name = "profile/decision_form.html"
@ -125,7 +140,9 @@ class DecisionUpdateView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTest
return reverse("profile:index")
class DecisionDeleteView(LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, DeleteView):
class DecisionDeleteView(
LoginRequiredMixin, SuccessMessageMixin, UserPassesTestMixin, DeleteView
):
model = Decision
template_name = "profile/decision_delete.html"
success_message = "Decision deleted successfully."

View File

@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tjdests.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tjdests.settings")
application = get_asgi_application()

View File

@ -21,7 +21,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-7nju0o%j&gz7&v^05iuq*tn$_iwvtjh1cq26@is(u2d4snkum5'
SECRET_KEY = "django-insecure-7nju0o%j&gz7&v^05iuq*tn$_iwvtjh1cq26@is(u2d4snkum5"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
@ -32,62 +32,61 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"crispy_forms",
"crispy_bootstrap5",
"social_django",
"django_extensions",
"bootstrap_pagination",
'tjdests.apps.authentication',
'tjdests.apps.destinations',
"tjdests.apps.authentication",
"tjdests.apps.destinations",
"tjdests.apps.profile",
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = 'tjdests.urls'
ROOT_URLCONF = "tjdests.urls"
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'tjdests.apps.context_processors.settings_renderer',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"tjdests.apps.context_processors.settings_renderer",
],
},
},
]
WSGI_APPLICATION = 'tjdests.wsgi.application'
WSGI_APPLICATION = "tjdests.wsgi.application"
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
@ -97,22 +96,25 @@ DATABASES = {
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
AUTH_USER_MODEL = "authentication.User"
AUTHENTICATION_BACKENDS = ("tjdests.apps.authentication.oauth.IonOauth2", "django.contrib.auth.backends.ModelBackend",)
AUTHENTICATION_BACKENDS = (
"tjdests.apps.authentication.oauth.IonOauth2",
"django.contrib.auth.backends.ModelBackend",
)
SOCIAL_AUTH_REDIRECT_IS_HTTPS = False
SOCIAL_AUTH_ION_KEY = ""
@ -122,9 +124,9 @@ SOCIAL_AUTH_ION_SECRET = ""
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = "en-us"
TIME_ZONE = 'UTC'
TIME_ZONE = "UTC"
USE_I18N = True
@ -136,14 +138,14 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "serve/")
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static/"),)
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
LOGIN_REDIRECT_URL = "authentication:tos"
LOGOUT_REDIRECT_URL = "authentication:index"

View File

@ -10,7 +10,7 @@ DEBUG = True
ALLOWED_HOSTS = []
# secret
SECRET_KEY = 'supersecret'
SECRET_KEY = "supersecret"
# OAuth
SOCIAL_AUTH_ION_KEY = "ionkey"

View File

@ -14,12 +14,15 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.urls import include, path
urlpatterns = [
path('djangoadmin/', admin.site.urls),
path("djangoadmin/", admin.site.urls),
path("", include("tjdests.apps.authentication.urls", namespace="authentication")),
path("oauth/", include("social_django.urls", namespace="social")),
path("destinations/", include("tjdests.apps.destinations.urls", namespace="destinations")),
path(
"destinations/",
include("tjdests.apps.destinations.urls", namespace="destinations"),
),
path("profile/", include("tjdests.apps.profile.urls", namespace="profile")),
]

View File

@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tjdests.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tjdests.settings")
application = get_wsgi_application()