Working model logic and views
This commit is contained in:
parent
a6441ffb63
commit
02bb53d84e
10 changed files with 224 additions and 89 deletions
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"emmet.includeLanguages": {
|
||||
"jinja-html": "html"
|
||||
},
|
||||
"editor.defaultFormatter": null
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
|
|||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from django.contrib.messages import constants
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
|
@ -23,10 +24,12 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||
SECRET_KEY = 'django-insecure-+m#ore4ojw1s_+yo+kutzpi^asg2dg9+f3+rf(hr#o)73ifo_1'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = [
|
||||
'localhost',
|
||||
'127.0.0.1'
|
||||
]
|
||||
|
||||
# Application definition
|
||||
|
||||
|
|
@ -56,7 +59,7 @@ ROOT_URLCONF = 'CollegiateHouseWars.urls'
|
|||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'DIRS': [BASE_DIR / 'templates'],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
|
|
@ -123,3 +126,10 @@ STATIC_URL = 'static/'
|
|||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
|
||||
MESSAGE_TAGS = {constants.DEBUG: 'debug',
|
||||
constants.INFO: 'info',
|
||||
constants.SUCCESS: 'success',
|
||||
constants.WARNING: 'warning',
|
||||
constants.ERROR: 'danger', }
|
||||
|
|
|
|||
|
|
@ -2,23 +2,16 @@ from django.contrib import admin
|
|||
from .models import Activity, Entry
|
||||
|
||||
|
||||
@admin.action(description='Reset signup counter')
|
||||
def resetSignupCounters(modeladmin, request, queryset):
|
||||
queryset.update(session1_signups=0, session2_signups=0)
|
||||
|
||||
|
||||
class ActivityAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
(None, {'fields': ['name']}),
|
||||
('Activity Information', {
|
||||
'fields': ['quota', 'time', 'session1_signups', 'session2_signups']}),
|
||||
'fields': ['quota', 'time']}),
|
||||
]
|
||||
|
||||
list_display = ('name', 'time', 'quota',
|
||||
'session1_signups', 'session2_signups')
|
||||
|
||||
actions = [resetSignupCounters]
|
||||
|
||||
|
||||
class EntryAdmin(admin.ModelAdmin):
|
||||
fieldsets = [
|
||||
|
|
@ -31,7 +24,7 @@ class EntryAdmin(admin.ModelAdmin):
|
|||
list_display = ('first_name', 'last_name',
|
||||
'house', 'activity1', 'activity2')
|
||||
|
||||
list_filter = ['house', 'grade']
|
||||
list_filter = ['house', 'grade', 'activity1', 'activity2']
|
||||
|
||||
|
||||
# Register your models here.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from django.forms import ModelForm
|
||||
from django.forms import ModelForm, TextInput, EmailInput, Select
|
||||
from django.db.models import F
|
||||
|
||||
from .models import Entry, Activity
|
||||
|
|
@ -10,12 +10,48 @@ class EntryForm(ModelForm):
|
|||
model = Entry
|
||||
fields = '__all__'
|
||||
|
||||
widgets = {
|
||||
'first_name': TextInput(attrs={
|
||||
'class': 'form-control',
|
||||
'id': 'first-name',
|
||||
'placeholder': 'First Name'
|
||||
}),
|
||||
'last_name': TextInput(attrs={
|
||||
'class': "form-control",
|
||||
'id': 'last-name',
|
||||
'placeholder': 'Last Name'
|
||||
}),
|
||||
'email': EmailInput(attrs={
|
||||
'class': "form-control",
|
||||
'id': 'email',
|
||||
'placeholder': 'Email'
|
||||
}),
|
||||
'grade': Select(attrs={
|
||||
'class': "form-select",
|
||||
'id': 'grade',
|
||||
'placeholder': 'Grade'
|
||||
}),
|
||||
'house': Select(attrs={
|
||||
'class': "form-select",
|
||||
'id': 'house',
|
||||
'placeholder': 'House'
|
||||
}),
|
||||
'activity1': Select(attrs={
|
||||
'class': "form-select",
|
||||
'id': 'activity1',
|
||||
'placeholder': 'Activity 1'
|
||||
}),
|
||||
'activity2': Select(attrs={
|
||||
'class': "form-select",
|
||||
'id': 'activity2',
|
||||
'placeholder': 'Activity 2'
|
||||
}),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
filtered1 = Activity.objects.filter(
|
||||
session1_signups__lt=F('quota'))
|
||||
filtered2 = Activity.objects.filter(
|
||||
time=30).filter(session2_signups__lt=F('quota'))
|
||||
filtered1 = Activity.session1.below_quota()
|
||||
filtered2 = Activity.session2.below_quota()
|
||||
|
||||
self.fields['activity1'].queryset = filtered1
|
||||
self.fields['activity2'].queryset = filtered2
|
||||
|
|
|
|||
20
housewars/managers.py
Normal file
20
housewars/managers.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from django.db.models import Manager, F
|
||||
|
||||
|
||||
class Session1Activities(Manager):
|
||||
def below_quota(self):
|
||||
signupIDs = [act.id for act in self.get_queryset() if act.quota >
|
||||
act.session1_signups]
|
||||
|
||||
return self.filter(id__in=signupIDs).order_by('time', 'name')
|
||||
|
||||
|
||||
class Session2Activities(Manager):
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(time=30)
|
||||
|
||||
def below_quota(self):
|
||||
signupIDs = [act.id for act in self.filter(time=30) if act.quota >
|
||||
act.session2_signups]
|
||||
|
||||
return self.filter(id__in=signupIDs).order_by('name')
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 4.0.4 on 2022-05-17 22:36
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('housewars', '0009_alter_activity_session1_signups_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='activity',
|
||||
name='session1_signups',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='activity',
|
||||
name='session2_signups',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
from django.db import models
|
||||
from django.forms import ValidationError
|
||||
from django.db.models import F
|
||||
|
||||
# Create your models here.
|
||||
from .managers import Session1Activities, Session2Activities
|
||||
|
||||
|
||||
class Activity(models.Model):
|
||||
|
|
@ -16,10 +15,19 @@ class Activity(models.Model):
|
|||
|
||||
name = models.CharField(max_length=100)
|
||||
quota = models.IntegerField()
|
||||
session1_signups = models.IntegerField(default=0)
|
||||
session2_signups = models.IntegerField(default=0)
|
||||
time = models.IntegerField(choices=TimeslotChoices)
|
||||
|
||||
session1 = Session1Activities()
|
||||
session2 = Session2Activities()
|
||||
|
||||
@property
|
||||
def session1_signups(self):
|
||||
return Entry.objects.filter(activity1=self).count()
|
||||
|
||||
@property
|
||||
def session2_signups(self):
|
||||
return Entry.objects.filter(activity2=self).count()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.time})"
|
||||
|
||||
|
|
@ -53,28 +61,14 @@ class Entry(models.Model):
|
|||
Activity, related_name='activity2', on_delete=models.CASCADE, blank=True, null=True)
|
||||
|
||||
def clean(self):
|
||||
if self.activity2:
|
||||
if self.activity1.time + self.activity2.time != 60:
|
||||
raise ValidationError(
|
||||
"Please pick activities adding up to one hour.")
|
||||
else:
|
||||
super().clean()
|
||||
if self.activity2 and self.activity1.time + self.activity2.time != 60:
|
||||
raise ValidationError(
|
||||
"Please pick activities adding up to one hour.")
|
||||
elif not self.activity2 and self.activity1.time != 60:
|
||||
raise ValidationError(
|
||||
"Please pick activities adding up to one hour.")
|
||||
else:
|
||||
if self.activity1.time != 60:
|
||||
raise ValidationError(
|
||||
"Please pick activities adding up to one hour.")
|
||||
else:
|
||||
super().clean()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if (self.activity1):
|
||||
self.activity1.session1_signups += 1
|
||||
self.activity1.save()
|
||||
if (self.activity2):
|
||||
self.activity2.session2_signups += 1
|
||||
self.activity2.save()
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
super().clean()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
|
|
|||
|
|
@ -1,44 +1,44 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="ISO-8859-1" />
|
||||
<meta name="description" content="A website made by C4 Patino" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% if title %}
|
||||
<title>Django Blog - {{title}}</title>
|
||||
{% else %}
|
||||
<title>Django Blog</title>
|
||||
{% endif %}
|
||||
</head>
|
||||
<body>
|
||||
<main role="main" class="container">
|
||||
<div class="content-section">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<fieldset class="form-group">
|
||||
<legend class="border-bottom mb-4">
|
||||
House Wars Signup
|
||||
</legend>
|
||||
{{ form.as_p }}
|
||||
</fieldset>
|
||||
<div>
|
||||
<button class="btn btn-outline-info" type="submit">
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% block content %}
|
||||
<div class="content-section">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<fieldset class="form-group" id="name">
|
||||
<legend class="border-bottom mb-4">House Wars Signup</legend>
|
||||
</fieldset>
|
||||
<label for="name" class="form-label">Name:</label>
|
||||
<div class="row mb-3" id="name">
|
||||
<div class="col">
|
||||
{{ form.first_name }}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ form.last_name }}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Email:</label>
|
||||
{{ form.email }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="grade" class="form-label">Grade:</label>
|
||||
{{ form.grade }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="house" class="form-label">House:</label>
|
||||
{{ form.house }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="activity1" class="form-label">Activity 1:</label>
|
||||
{{ form.activity1 }}
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="activity2" class="form-label">Activity 2:</label>
|
||||
{{ form.activity2 }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input class="btn btn-outline-primary" type="submit" value="Submit" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from django.shortcuts import redirect
|
||||
from django.shortcuts import render
|
||||
from django.contrib import messages
|
||||
from django.urls import reverse
|
||||
from django.views.generic import CreateView
|
||||
|
||||
|
|
@ -7,11 +8,27 @@ from .forms import EntryForm
|
|||
|
||||
|
||||
class EntryCreateView(CreateView):
|
||||
model = Entry
|
||||
form_class = EntryForm
|
||||
template_name = 'housewars/entry_form.html'
|
||||
|
||||
def post(self, request):
|
||||
form = self.form_class(request.POST)
|
||||
if form.is_valid():
|
||||
messages.success(request, 'Your entry has been submitted')
|
||||
return super().post(request)
|
||||
|
||||
messages.error(
|
||||
request, 'Please enter activities adding up to one hour.')
|
||||
return render(request, self.template_name, {'form': form})
|
||||
|
||||
def form_valid(self, form):
|
||||
prev = Entry.objects.filter(email=form.cleaned_data['email'])
|
||||
for entry in prev:
|
||||
entry.delete()
|
||||
|
||||
print('form valid')
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('housewars:create_entry')
|
||||
|
||||
def form_valid(self, form):
|
||||
return super().form_valid(form)
|
||||
|
|
|
|||
38
templates/base.html
Normal file
38
templates/base.html
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="ISO-8859-1" />
|
||||
<meta name="description" content="A website made by C4 Patino" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
|
||||
<link rel="stylesheet" type="text/css" href='{% static "main.css" %}' />
|
||||
|
||||
<title>House Wars</title>
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header"></header>
|
||||
<main role="main" class="container">
|
||||
<div class="row">
|
||||
<!-- Message Display -->
|
||||
<div class="col-md-8">
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<!-- Main content -->
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in a new issue