Updated award field
This commit is contained in:
parent
d9d0057fa4
commit
8aabb4f46d
11 changed files with 98 additions and 36 deletions
|
|
@ -12,6 +12,7 @@ import csv
|
|||
import io
|
||||
|
||||
from ..models import UserEntry
|
||||
from ..utils import unpack_values
|
||||
|
||||
|
||||
class MentorListFilter(admin.SimpleListFilter):
|
||||
|
|
@ -69,23 +70,14 @@ class UserEntryAdmin(admin.ModelAdmin):
|
|||
|
||||
@admin.action(description='Export selected to csv')
|
||||
def export_to_csv(self, request, queryset):
|
||||
field_names = [field.name for field in queryset.model._meta.fields]
|
||||
|
||||
response = HttpResponse(content_type='text/csv', headers={
|
||||
'Content-Disposition': 'attachment; filename="export.csv"'},)
|
||||
|
||||
writer = csv.writer(response, delimiter=";")
|
||||
# Write a first row with header information
|
||||
writer.writerow(field_names)
|
||||
# Write data rows
|
||||
for row in queryset:
|
||||
values = []
|
||||
for field in field_names:
|
||||
value = getattr(row, field)
|
||||
if value is None:
|
||||
value = ''
|
||||
values.append(value)
|
||||
writer.writerow(values)
|
||||
|
||||
# Unpack dataset and write to file
|
||||
data = unpack_values(queryset)
|
||||
writer.writerows(data)
|
||||
|
||||
return response
|
||||
|
||||
|
|
@ -93,28 +85,19 @@ class UserEntryAdmin(admin.ModelAdmin):
|
|||
def export_to_pdf(self, request, queryset):
|
||||
buffer = io.BytesIO()
|
||||
doc = SimpleDocTemplate(buffer, pagesize=letter)
|
||||
|
||||
elements = []
|
||||
|
||||
field_names = [field.name for field in queryset.model._meta.fields]
|
||||
data = []
|
||||
data.append(field_names)
|
||||
for row in queryset:
|
||||
values = []
|
||||
for field in field_names:
|
||||
value = getattr(row, field)
|
||||
if value is None:
|
||||
value = ''
|
||||
values.append(value)
|
||||
data.append(values)
|
||||
|
||||
# Unpack queryset data and load into table
|
||||
data = unpack_values(queryset)
|
||||
table = Table(data, repeatRows=1)
|
||||
table.setStyle(TableStyle(
|
||||
[('INNERGRID', (0, 0), (-1, -1), 0.25, black), ('BOX', (0, 0), (-1, -1), 0.25, black)]))
|
||||
|
||||
# Load table into PDF file
|
||||
elements.append(table)
|
||||
|
||||
# Build document
|
||||
doc.build(elements)
|
||||
|
||||
buffer.seek(0)
|
||||
|
||||
return FileResponse(buffer, as_attachment=True, filename='download.pdf')
|
||||
|
|
|
|||
|
|
@ -35,10 +35,13 @@ class UserEntryForm(Form):
|
|||
|
||||
def clean(self):
|
||||
email = self.cleaned_data['email']
|
||||
# Verify that email domain matches the school's
|
||||
if ('@slps.org' not in email):
|
||||
raise ValidationError("Please use your school email")
|
||||
# Verify that no other email with that domain exists
|
||||
if UserEntry.objects.filter(email=email).exists():
|
||||
raise ValidationError("A signup with this email already exists")
|
||||
raise ValidationError(
|
||||
"A signup with this email already exists, if you want to change your signups, please email cpatino8605@slps.org")
|
||||
|
||||
|
||||
class ActivityForm(Form):
|
||||
|
|
@ -59,6 +62,7 @@ class ActivityForm(Form):
|
|||
activity1 = data.get('activity1')
|
||||
activity2 = data.get('activity2')
|
||||
|
||||
# Verify that there are 60 minutes of activities selected
|
||||
if activity1:
|
||||
if activity2 and activity1.time + activity2.time != 60:
|
||||
raise ValidationError(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 4.0.4 on 2022-09-03 16:59
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('housewars', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='pointsentry',
|
||||
unique_together={('activity', 'award')},
|
||||
),
|
||||
]
|
||||
18
housewars/migrations/0003_alter_activity_time.py
Normal file
18
housewars/migrations/0003_alter_activity_time.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.0.4 on 2022-09-03 19:58
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('housewars', '0002_alter_pointsentry_unique_together'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='time',
|
||||
field=models.IntegerField(choices=[(30, '30'), (60, '60')]),
|
||||
),
|
||||
]
|
||||
|
|
@ -12,12 +12,12 @@ class Activity(models.Model):
|
|||
|
||||
name = models.CharField(max_length=100)
|
||||
default_quota = models.IntegerField(default=0)
|
||||
time = models.IntegerField(choices=TimeslotChoices, blank=True, null=True)
|
||||
time = models.IntegerField(choices=TimeslotChoices)
|
||||
password = models.CharField(
|
||||
max_length=100, blank=True, null=True, default=None)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name}"
|
||||
return f"{self.name} ({self.time})"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.full_clean()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class Award(models.Model):
|
|||
points = models.IntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.activity})"
|
||||
return f"{self.name}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.full_clean()
|
||||
|
|
|
|||
|
|
@ -34,16 +34,13 @@ class UserEntry(models.Model):
|
|||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
def clean(self):
|
||||
# Check to verify that there are 60 minutes of activities
|
||||
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.")
|
||||
if (self.activity1 and self.activity1.time == None):
|
||||
raise ValidationError('You cannot sign up for a null activity')
|
||||
if (self.activity2 and self.activity2.time == None):
|
||||
raise ValidationError('You cannot sign up for a null activity')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.full_clean()
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
from .get_random_string import get_random_string
|
||||
from .unpack_values import unpack_values
|
||||
|
|
|
|||
|
|
@ -3,7 +3,19 @@ import string
|
|||
|
||||
|
||||
def get_random_string(length):
|
||||
# choose from all lowercase letter
|
||||
"""Generates a random string of length n
|
||||
|
||||
Parameters
|
||||
----------
|
||||
length : int
|
||||
The desired length of the returned string
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
A random string of length n
|
||||
"""
|
||||
|
||||
letters = string.ascii_lowercase
|
||||
result_str = ''.join(random.choice(letters) for i in range(length))
|
||||
return result_str
|
||||
|
|
|
|||
27
housewars/utils/unpack_values.py
Normal file
27
housewars/utils/unpack_values.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
def unpack_values(queryset):
|
||||
"""Unpacks a queryset into a 2D array
|
||||
|
||||
Parameters
|
||||
----------
|
||||
queryset : int
|
||||
The queryset that will be unpacked
|
||||
|
||||
Returns
|
||||
-------
|
||||
data : [list]
|
||||
A random string of length n
|
||||
"""
|
||||
|
||||
field_names = [field.name for field in queryset.model._meta.fields]
|
||||
data = []
|
||||
data.append(field_names)
|
||||
for row in queryset:
|
||||
values = []
|
||||
for field in field_names:
|
||||
value = getattr(row, field)
|
||||
if value is None:
|
||||
value = ''
|
||||
values.append(value)
|
||||
data.append(values)
|
||||
|
||||
return data
|
||||
|
|
@ -38,15 +38,18 @@ class EntryCreateView(SessionWizardView):
|
|||
if step == 'activity':
|
||||
cd = self.storage.get_step_data('user')
|
||||
|
||||
# Retrieve custom quotas for house activities
|
||||
quota = Quota.objects.filter(
|
||||
house=cd.get('user-house'), activity=OuterRef('id')).values('quota')
|
||||
|
||||
# Set quota to custom quota or default, then set count to the total signups for each activity. Filter where quota is less than house signups.
|
||||
filtered1 = Activity.objects.filter(time__isnull=False).annotate(final_quota=Coalesce(Subquery(quota[:1]), F('default_quota'))).annotate(count=Count(
|
||||
'activity1', filter=Q(activity1__house=cd.get('user-house')))).filter(final_quota__gt=F('count'))
|
||||
|
||||
filtered2 = Activity.objects.filter(time__isnull=False).annotate(final_quota=Coalesce(Subquery(quota[:1]), F('default_quota'))).annotate(count=Count(
|
||||
'activity1', filter=Q(activity1__house=cd.get('user-house')))).filter(final_quota__gt=F('count'), time=30)
|
||||
|
||||
# Render filtered as choices in activity select step
|
||||
form.fields['activity1'].queryset = filtered1
|
||||
form.fields['activity2'].queryset = filtered2
|
||||
|
||||
|
|
|
|||
Reference in a new issue