From 50478a72728d75ae4b36aa456e1ebe5df5bdb8e5 Mon Sep 17 00:00:00 2001 From: imaegg11 Date: Sun, 27 Oct 2024 22:24:33 -0400 Subject: [PATCH 1/5] I have no idea what I am doing --- core/admin.py | 52 +++++++++++++++++++++++++++++++- core/forms.py | 12 ++++++++ core/models/course.py | 2 +- templates/admin/custom_form.html | 40 ++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 templates/admin/custom_form.html diff --git a/core/admin.py b/core/admin.py index a1753690..66bbe4a7 100644 --- a/core/admin.py +++ b/core/admin.py @@ -24,6 +24,7 @@ TermAdminForm, UserAdminForm, UserCreationAdminForm, + LateStartEventForm ) from .models import Comment, StaffMember from .utils.actions import ( @@ -48,6 +49,11 @@ PostTypeFilter, ) +from django.template.response import TemplateResponse +from django.shortcuts import redirect +from django.urls import path +from datetime import datetime, time + User = get_user_model() # Register your models here. @@ -546,13 +552,57 @@ def formfield_for_manytomany(self, db_field, request, **kwargs): kwargs["queryset"] = models.Tag.objects.all().order_by("name") return super().formfield_for_manytomany(db_field, request, **kwargs) - class EventAdmin(CustomTimeMixin, admin.ModelAdmin): list_display = ["name", "organization", "start_date", "end_date"] list_filter = [OrganizationListFilter] ordering = ["-start_date", "-end_date"] search_fields = ["name"] + def get_urls(self): + return [ + path( + "createLateStart/", + self.admin_site.admin_view(self.late_start_view) + ), + *super().get_urls(), + ] + + def late_start_view(self, request): + + url = request.get_full_path() + + context = dict( + self.admin_site.each_context(request), + form=LateStartEventForm, + url=url, + title='Add Late Start', + media=LateStartEventForm().media + ) + + if request.method == 'POST': + form = LateStartEventForm(request.POST) + if form.is_valid(): + start_date_value = form.cleaned_data.get('start_date') + start_date = datetime.combine(start_date_value, time(hour=10)) + end_date = datetime.combine(start_date_value, time(hour=10, second=1)) + + data = { + 'name': 'Late Start', + 'term': models.Term.get_current(start_date), + 'organization': models.Organization.objects.get(name='SAC'), + 'schedule_format': 'late-start', + 'start_date': start_date, + 'end_date': end_date + } + + models.Event.objects.create(**data) + return redirect("/admin/core/event") + else: + context['form'] = form + return TemplateResponse(request, "admin/custom_form.html", context) + else: + return TemplateResponse(request, "admin/custom_form.html", context) + def get_queryset(self, request): qs = super().get_queryset(request) if request.user.is_superuser: diff --git a/core/forms.py b/core/forms.py index d7642116..5ebc0db7 100644 --- a/core/forms.py +++ b/core/forms.py @@ -5,6 +5,7 @@ from django.contrib.auth.forms import ( AdminUserCreationForm as ContribAdminUserCreationForm, ) +from django.contrib.admin.widgets import AdminDateWidget from django.utils import timezone from django_select2 import forms as s2forms from martor.widgets import AdminMartorWidget @@ -13,6 +14,7 @@ from core.views.mixins import CaseInsensitiveUsernameMixin + class MetropolisSignupForm(SignupForm, CaseInsensitiveUsernameMixin): first_name = forms.CharField( max_length=30, @@ -295,3 +297,13 @@ class UserAdminForm(CaseInsensitiveUsernameMixin, ContribUserChangeForm): class UserCreationAdminForm(CaseInsensitiveUsernameMixin, ContribAdminUserCreationForm): pass + +class LateStartEventForm(forms.Form): + start_date = forms.DateField(widget=AdminDateWidget()) + + def clean(self): + cleaned_data = super().clean() + if cleaned_data.get('start_date') != None and models.Term.get_current(cleaned_data['start_date']) == None: + raise forms.ValidationError( + {'start_date': 'No Term Found For Date'} + ) \ No newline at end of file diff --git a/core/models/course.py b/core/models/course.py index c429662d..c45669aa 100644 --- a/core/models/course.py +++ b/core/models/course.py @@ -266,7 +266,7 @@ def get_events(cls, user=None): return events def clean(self): - if self.start_date > self.end_date: + if self.start_date != None and self.end_date != None and self.start_date > self.end_date: raise ValidationError( { "start_date": _("Start date must be before end date"), diff --git a/templates/admin/custom_form.html b/templates/admin/custom_form.html new file mode 100644 index 00000000..16874353 --- /dev/null +++ b/templates/admin/custom_form.html @@ -0,0 +1,40 @@ +{% extends "admin/base_site.html" %} +{% load i18n admin_urls static admin_modify %} + +{% block extrahead %} + {{ block.super }} + + + {{ media }} +{% endblock %} + +{% block extrastyle %} + {{ block.super }} + +{% endblock %} + +{% if not is_popup %} + {% block breadcrumbs %}{% endblock %} +{% endif %} + +{% block coltype %}colM{% endblock %} +{% block content %} +
+ {% csrf_token %} +
+ {% for field in form %} +
+ {{ field.errors }} +
+
+ {{ field.label_tag }} {{ field }} +
+
+
+ {% endfor %} +
+
+ +
+
+{% endblock %} From 5aeb97c9710f208aa48cfd21ea0066c8bf5dae32 Mon Sep 17 00:00:00 2001 From: imaegg11 Date: Thu, 31 Oct 2024 20:30:27 -0400 Subject: [PATCH 2/5] Added field for organization that defaults to any named SAC --- core/admin.py | 4 +++- core/forms.py | 13 +++++++++++++ templates/admin/custom_form.html | 9 +++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/core/admin.py b/core/admin.py index 66bbe4a7..70166e62 100644 --- a/core/admin.py +++ b/core/admin.py @@ -586,10 +586,12 @@ def late_start_view(self, request): start_date = datetime.combine(start_date_value, time(hour=10)) end_date = datetime.combine(start_date_value, time(hour=10, second=1)) + organization = form.cleaned_data.get('organization') + data = { 'name': 'Late Start', 'term': models.Term.get_current(start_date), - 'organization': models.Organization.objects.get(name='SAC'), + 'organization': organization, 'schedule_format': 'late-start', 'start_date': start_date, 'end_date': end_date diff --git a/core/forms.py b/core/forms.py index 5ebc0db7..1b37dad5 100644 --- a/core/forms.py +++ b/core/forms.py @@ -300,6 +300,19 @@ class UserCreationAdminForm(CaseInsensitiveUsernameMixin, ContribAdminUserCreati class LateStartEventForm(forms.Form): start_date = forms.DateField(widget=AdminDateWidget()) + organization = forms.ModelChoiceField( + queryset=models.Organization.objects.all(), + required=True + ) + + def __init__(self, *args, **kwargs): + super(LateStartEventForm, self).__init__(*args, **kwargs) + + try: + self.fields["organization"].initial = models.Organization.objects.get(name='SAC') + except models.Organization.DoesNotExist: + pass + def clean(self): cleaned_data = super().clean() diff --git a/templates/admin/custom_form.html b/templates/admin/custom_form.html index 16874353..a184d19c 100644 --- a/templates/admin/custom_form.html +++ b/templates/admin/custom_form.html @@ -21,6 +21,15 @@ {% block content %}
{% csrf_token %} + {% if form.errors %} +

+ {% if form.errors|length == 1 %} + {% translate "Please correct the error below." %} + {% else %} + {% translate "Please correct the errors below." %} + {% endif %} +

+ {% endif %}
{% for field in form %}
From 2606157163b4f72c7648bc2322e6e4926e91b1b2 Mon Sep 17 00:00:00 2001 From: imaegg11 Date: Wed, 6 Nov 2024 17:47:08 -0500 Subject: [PATCH 3/5] Made accessible from events page (More templates!!!) --- core/admin.py | 37 +++++++++++++++++++++--- core/forms.py | 13 --------- core/models/course.py | 2 +- templates/admin/change_list_buttons.html | 10 +++++++ 4 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 templates/admin/change_list_buttons.html diff --git a/core/admin.py b/core/admin.py index 70166e62..da616a93 100644 --- a/core/admin.py +++ b/core/admin.py @@ -557,12 +557,24 @@ class EventAdmin(CustomTimeMixin, admin.ModelAdmin): list_filter = [OrganizationListFilter] ordering = ["-start_date", "-end_date"] search_fields = ["name"] + change_list_template = 'admin/change_list_custom_buttons.html' + + def changelist_view(self, request, extra_context=None): + extra_context = extra_context or {} + extra_context['buttons'] = [ + { + 'name': 'Add Late Start', + 'url': reverse('admin:late_start'), + }, + ] + return super().changelist_view(request, extra_context=extra_context) def get_urls(self): return [ path( "createLateStart/", - self.admin_site.admin_view(self.late_start_view) + self.admin_site.admin_view(self.late_start_view), + name="late_start" ), *super().get_urls(), ] @@ -586,17 +598,34 @@ def late_start_view(self, request): start_date = datetime.combine(start_date_value, time(hour=10)) end_date = datetime.combine(start_date_value, time(hour=10, second=1)) - organization = form.cleaned_data.get('organization') - data = { 'name': 'Late Start', 'term': models.Term.get_current(start_date), - 'organization': organization, 'schedule_format': 'late-start', 'start_date': start_date, 'end_date': end_date } + try: + data["organization"] = models.Organization.objects.get(name='SAC') + except models.Organization.DoesNotExist: + + earliest_superuser = models.User.objects.filter(is_superuser=True).earliest("date_joined") + + organization_data = { + 'bio': 'WLMAC Student Activity Council', + 'is_open': False, + 'name': 'SAC', + 'slug': 'wlmac', + 'owner': earliest_superuser + } + + sac_org = models.Organization.objects.create(**organization_data) + sac_org.execs.add(earliest_superuser) + sac_org.save() + + data["organization"] = sac_org + models.Event.objects.create(**data) return redirect("/admin/core/event") else: diff --git a/core/forms.py b/core/forms.py index 1b37dad5..5ebc0db7 100644 --- a/core/forms.py +++ b/core/forms.py @@ -300,19 +300,6 @@ class UserCreationAdminForm(CaseInsensitiveUsernameMixin, ContribAdminUserCreati class LateStartEventForm(forms.Form): start_date = forms.DateField(widget=AdminDateWidget()) - organization = forms.ModelChoiceField( - queryset=models.Organization.objects.all(), - required=True - ) - - def __init__(self, *args, **kwargs): - super(LateStartEventForm, self).__init__(*args, **kwargs) - - try: - self.fields["organization"].initial = models.Organization.objects.get(name='SAC') - except models.Organization.DoesNotExist: - pass - def clean(self): cleaned_data = super().clean() diff --git a/core/models/course.py b/core/models/course.py index c45669aa..c429662d 100644 --- a/core/models/course.py +++ b/core/models/course.py @@ -266,7 +266,7 @@ def get_events(cls, user=None): return events def clean(self): - if self.start_date != None and self.end_date != None and self.start_date > self.end_date: + if self.start_date > self.end_date: raise ValidationError( { "start_date": _("Start date must be before end date"), diff --git a/templates/admin/change_list_buttons.html b/templates/admin/change_list_buttons.html new file mode 100644 index 00000000..8b8573b3 --- /dev/null +++ b/templates/admin/change_list_buttons.html @@ -0,0 +1,10 @@ +{% extends "admin/change_list.html" %} +{% load i18n admin_urls static admin_list %} +{% block object-tools-items %} + {% for button in buttons %} +
  • + {{ button.name }} +
  • + {% endfor %} + {{ block.super }} +{% endblock %} From 57afa2fcb0b3d6c8f6526d08a752276867766bdf Mon Sep 17 00:00:00 2001 From: imaegg11 Date: Wed, 6 Nov 2024 17:52:47 -0500 Subject: [PATCH 4/5] Renamed template file name --- core/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin.py b/core/admin.py index da616a93..2336a23a 100644 --- a/core/admin.py +++ b/core/admin.py @@ -557,7 +557,7 @@ class EventAdmin(CustomTimeMixin, admin.ModelAdmin): list_filter = [OrganizationListFilter] ordering = ["-start_date", "-end_date"] search_fields = ["name"] - change_list_template = 'admin/change_list_custom_buttons.html' + change_list_template = 'admin/change_list_buttons.html' def changelist_view(self, request, extra_context=None): extra_context = extra_context or {} From 3bc9373948ca79930d3508da41c2f170849a2165 Mon Sep 17 00:00:00 2001 From: imaegg11 Date: Fri, 8 Nov 2024 17:29:47 -0500 Subject: [PATCH 5/5] Permission Checks --- core/admin.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/admin.py b/core/admin.py index 2336a23a..f3163ff5 100644 --- a/core/admin.py +++ b/core/admin.py @@ -53,6 +53,7 @@ from django.shortcuts import redirect from django.urls import path from datetime import datetime, time +from django.core.exceptions import PermissionDenied User = get_user_model() @@ -580,6 +581,9 @@ def get_urls(self): ] def late_start_view(self, request): + + if not request.user.has_perm('core.add_event'): + raise PermissionDenied() url = request.get_full_path() @@ -610,6 +614,9 @@ def late_start_view(self, request): data["organization"] = models.Organization.objects.get(name='SAC') except models.Organization.DoesNotExist: + if not request.user.has_perm('core.add_organization'): + raise PermissionDenied() + earliest_superuser = models.User.objects.filter(is_superuser=True).earliest("date_joined") organization_data = {