From 2fe9078e627a5e4cac0590283428568c25d03b4f Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sun, 11 Feb 2024 23:01:52 +0100 Subject: [PATCH 01/18] Integrated unfold admin & added important models fields to filter, display & search --- accounts/admin.py | 59 +++++++++++++++++++++++++++++++++++ course_management/settings.py | 15 ++++++--- courses/admin.py | 47 ++++++++++++++++++---------- 3 files changed, 101 insertions(+), 20 deletions(-) diff --git a/accounts/admin.py b/accounts/admin.py index 8c38f3f..bce147c 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -1,3 +1,62 @@ from django.contrib import admin +from unfold.admin import ModelAdmin +from django.contrib.auth.models import Group # Register your models here. +from allauth.account.models import EmailAddress +from allauth.account.admin import EmailAddressAdmin +from allauth.socialaccount.models import SocialAccount, SocialToken, SocialApp +from allauth.socialaccount.admin import ( + SocialAccountAdmin, + SocialTokenAdmin, + SocialAppAdmin, +) +from django.contrib.sites.admin import SiteAdmin +from django.contrib.sites.models import Site + +admin.site.unregister(Group) + + +@admin.register(Group) +class GroupAdmin(ModelAdmin): + pass + + +admin.site.unregister(EmailAddress) + + +@admin.register(EmailAddress) +class EmailAddressAdmin(ModelAdmin): + pass + + +admin.site.unregister(SocialAccount) + + +@admin.register(SocialAccount) +class SocialAccountAdmin(ModelAdmin): + pass + + +admin.site.unregister(SocialToken) + + +@admin.register(SocialToken) +class SocialTokenAdmin(ModelAdmin): + pass + + +admin.site.unregister(SocialApp) + + +@admin.register(SocialApp) +class SocialAppAdmin(ModelAdmin): + pass + + +admin.site.unregister(Site) + + +@admin.register(Site) +class SiteAdmin(ModelAdmin): + pass diff --git a/course_management/settings.py b/course_management/settings.py index ad7800a..6999e0b 100644 --- a/course_management/settings.py +++ b/course_management/settings.py @@ -34,6 +34,7 @@ ALLOWED_HOSTS = [ "localhost", + "127.0.0.1" ] + extra_allowed_hosts_parsed @@ -47,6 +48,7 @@ # Application definition INSTALLED_APPS = [ + "unfold", "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", @@ -109,12 +111,17 @@ # Database # https://docs.djangoproject.com/en/4.2/ref/settings/#databases -DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///db/db.sqlite3") -db_config = dj_database_url.config(default=DATABASE_URL) - -DATABASES = {"default": db_config} +# DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///db/db.sqlite3") +# db_config = dj_database_url.config(default=DATABASE_URL) +# DATABASES = {"default": db_config} +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} # Password validation # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators diff --git a/courses/admin.py b/courses/admin.py index db27eb4..809be04 100644 --- a/courses/admin.py +++ b/courses/admin.py @@ -1,5 +1,6 @@ from django import forms from django.contrib import admin +from unfold.admin import ModelAdmin from django.contrib import messages @@ -8,7 +9,27 @@ from .scoring import score_homework_submissions -admin.site.register(Course) +@admin.register(Course) +class CourseAdmin(ModelAdmin): + important_fields = ["title", "social_media_hashtag"] + list_display = important_fields + list_filter = important_fields + search_fields = important_fields + + +@admin.register(Project) +class ProjectAdmin(ModelAdmin): + important_fields = [ + "course", + "title", + "submission_due_date", + "learning_in_public_cap_project", + "peer_review_due_date", + "state", + ] + list_display = important_fields + list_filter = important_fields + search_fields = important_fields class QuestionForm(forms.ModelForm): @@ -32,25 +53,19 @@ def score_selected_homeworks(modeladmin, request, queryset): for homework in queryset: status, message = score_homework_submissions(homework.id) if status: - modeladmin.message_user( - request, message, level=messages.SUCCESS - ) + modeladmin.message_user(request, message, level=messages.SUCCESS) else: - modeladmin.message_user( - request, message, level=messages.WARNING - ) + modeladmin.message_user(request, message, level=messages.WARNING) -score_selected_homeworks.short_description = ( - "Score selected homeworks" -) +score_selected_homeworks.short_description = "Score selected homeworks" -class HomeworkAdmin(admin.ModelAdmin): +@admin.register(Homework) +class HomeworkAdmin(ModelAdmin): inlines = [QuestionInline] actions = [score_selected_homeworks] - - -admin.site.register(Homework, HomeworkAdmin) - -admin.site.register(Project) + important_fields = ["course", "title", "due_date", "is_scored"] + list_display = important_fields + list_filter = important_fields + search_fields = important_fields From c91f8eafd1eb65b96566fb9db381999ffc72c016 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sun, 11 Feb 2024 23:31:46 +0100 Subject: [PATCH 02/18] Fixed custom widgets conflict issue --- courses/admin.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/courses/admin.py b/courses/admin.py index 809be04..df8141e 100644 --- a/courses/admin.py +++ b/courses/admin.py @@ -1,6 +1,6 @@ from django import forms from django.contrib import admin -from unfold.admin import ModelAdmin +from unfold.admin import ModelAdmin, TabularInline from django.contrib import messages @@ -36,14 +36,9 @@ class QuestionForm(forms.ModelForm): class Meta: model = Question fields = "__all__" - widgets = { - "text": forms.TextInput(attrs={"size": "60"}), - "possible_answers": forms.Textarea(attrs={"cols": 60, "rows": 4}), - "correct_answer": forms.TextInput(attrs={"size": "20"}), - } -class QuestionInline(admin.TabularInline): # or admin.StackedInline +class QuestionInline(TabularInline): model = Question form = QuestionForm extra = 0 From 7000d5c7c76a8c861f5ee055bcdb30163fca222f Mon Sep 17 00:00:00 2001 From: Mohammed Date: Tue, 13 Feb 2024 18:29:02 +0100 Subject: [PATCH 03/18] Revert database configurations --- course_management/settings.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/course_management/settings.py b/course_management/settings.py index 6999e0b..0c4e891 100644 --- a/course_management/settings.py +++ b/course_management/settings.py @@ -33,8 +33,7 @@ extra_allowed_hosts_parsed = EXTRA_ALLOWED_HOSTS.split(",") ALLOWED_HOSTS = [ - "localhost", - "127.0.0.1" + "localhost" ] + extra_allowed_hosts_parsed @@ -111,17 +110,11 @@ # Database # https://docs.djangoproject.com/en/4.2/ref/settings/#databases -# DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///db/db.sqlite3") -# db_config = dj_database_url.config(default=DATABASE_URL) +DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///db/db.sqlite3") +db_config = dj_database_url.config(default=DATABASE_URL) -# DATABASES = {"default": db_config} +DATABASES = {"default": db_config} -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', - } -} # Password validation # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators From c986c0cb6b0e8c326ddfb70bbcc625fd9dd9f861 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Tue, 13 Feb 2024 22:24:30 +0100 Subject: [PATCH 04/18] Added django-unfold to pipfile --- Pipfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Pipfile b/Pipfile index 408a069..a99c4b2 100644 --- a/Pipfile +++ b/Pipfile @@ -11,6 +11,7 @@ whitenoise = "*" psycopg2-binary = "*" gunicorn = "*" python-json-logger = "*" +django-unfold = "*" [dev-packages] ipython = "*" From b034ec75452b45e37b52e74f5d040132b236b940 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Thu, 15 Feb 2024 15:20:32 +0100 Subject: [PATCH 05/18] Configured tailwind for use on admin custom widgets --- course_management/settings.py | 32 +++++++++++++++++++++++++++----- courses/admin.py | 10 ++++++++-- static/css/style.css | 3 +++ static/css/styles.css | 1 + tailwind.config.js | 7 +++++++ 5 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 static/css/style.css create mode 100644 static/css/styles.css create mode 100644 tailwind.config.js diff --git a/course_management/settings.py b/course_management/settings.py index 0c4e891..3251c51 100644 --- a/course_management/settings.py +++ b/course_management/settings.py @@ -16,6 +16,9 @@ from pathlib import Path import dj_database_url +from django.templatetags.static import static +from django.utils.translation import gettext_lazy as _ + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -149,13 +152,12 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.2/howto/static-files/ -STATIC_ROOT = BASE_DIR / "static" +STATIC_ROOT = BASE_DIR / "staticfiles" STATIC_URL = "static/" -# STATICFILES_DIRS = [ -# STATIC_ROOT, -# # Other directories here -# ] +STATICFILES_DIRS = [ + BASE_DIR / 'static', +] is_test = ("test" in sys.argv) or \ @@ -282,3 +284,23 @@ SOCIALACCOUNT_ADAPTER = ( "accounts.auth.ConsolidatingSocialAccountAdapter" ) + + +# Unfold Configurations +UNFOLD = { + "SITE_HEADER": _("Course Management"), + "SITE_TITLE": _("Course Management"), + "SITE_SYMBOL": "course", + "SHOW_HISTORY": False, + # "ENVIRONMENT": "formula.utils.environment_callback", + # "DASHBOARD_CALLBACK": "formula.views.dashboard_callback", + # "LOGIN": { + # "image": lambda request: static("images/login-bg.jpg"), + # }, + "STYLES": [ + lambda request: static("css/styles.css"), + ], + # "SCRIPTS": [ + # lambda request: static("js/chart.min.js"), + # ] +} \ No newline at end of file diff --git a/courses/admin.py b/courses/admin.py index df8141e..ccc02b6 100644 --- a/courses/admin.py +++ b/courses/admin.py @@ -36,8 +36,14 @@ class QuestionForm(forms.ModelForm): class Meta: model = Question fields = "__all__" - - + field_styles = "border bg-white font-medium rounded-md shadow-sm text-gray-500 text-sm focus:ring focus:ring-primary-300 focus:border-primary-600 focus:outline-none group-[.errors]:border-red-600 group-[.errors]:focus:ring-red-200 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-400 dark:focus:border-primary-600 dark:focus:ring-primary-700 dark:focus:ring-opacity-50 dark:group-[.errors]:border-red-500 dark:group-[.errors]:focus:ring-red-600/40 px-3 py-2 w-full" + widgets = { + "text": forms.TextInput(attrs={"size": "60", 'class': field_styles}), + "possible_answers": forms.Textarea(attrs={"cols": 60, "rows": 4, 'class': field_styles}), + "correct_answer": forms.TextInput(attrs={"size": "20", 'class': field_styles}), + } + + class QuestionInline(TabularInline): model = Question form = QuestionForm diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..bd6213e --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/static/css/styles.css b/static/css/styles.css new file mode 100644 index 0000000..e213969 --- /dev/null +++ b/static/css/styles.css @@ -0,0 +1 @@ +/*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.m-0{margin:0}.mx-2{margin-left:.5rem;margin-right:.5rem}.mb-3{margin-bottom:.75rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.w-full{width:100%}.w-\[50\]{width:50}.w-\[50\%\]{width:50%}.w-\[10\]{width:10}.w-\[10\%\]{width:10%}.w-\[10px\]{width:10px}.w-32{width:8rem}.max-w-2xl{max-width:42rem}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-none{flex:none}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.text-center{text-align:center}.text-right{text-align:right}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-primary-600:focus{--tw-border-opacity:1;border-color:rgb(var(--color-primary-600)/var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-primary-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--color-primary-300)/var(--tw-ring-opacity))}.group.errors .group-\[\.errors\]\:border-red-600{--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}.group.errors .group-\[\.errors\]\:focus\:ring-red-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(254 202 202/var(--tw-ring-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:bg-gray-900),:is(.dark :is(.dark .dark\:dark\:bg-gray-900)){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:focus\:border-primary-600:focus){--tw-border-opacity:1;border-color:rgb(var(--color-primary-600)/var(--tw-border-opacity))}:is(.dark .dark\:focus\:ring-primary-700:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(var(--color-primary-700)/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-opacity-50:focus){--tw-ring-opacity:0.5}:is(.dark .group.errors .dark\:group-\[\.errors\]\:border-red-500){--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity))}:is(.dark .group.errors .dark\:group-\[\.errors\]\:focus\:ring-red-600\/40:focus){--tw-ring-color:#dc262666} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..9e7dca6 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,7 @@ +module.exports = { + content: ["./**/*.{html,py,js}"], + media: false, + darkMode: "class", + theme: {}, + plugins: [], +}; From f8b5c779164ca75b63d36cef3ef2e3c91ca724e2 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Thu, 15 Feb 2024 15:20:38 +0100 Subject: [PATCH 06/18] format code --- accounts/admin.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/accounts/admin.py b/accounts/admin.py index bce147c..3c7cb21 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -16,47 +16,36 @@ admin.site.unregister(Group) - @admin.register(Group) class GroupAdmin(ModelAdmin): pass - admin.site.unregister(EmailAddress) - @admin.register(EmailAddress) class EmailAddressAdmin(ModelAdmin): pass - admin.site.unregister(SocialAccount) - @admin.register(SocialAccount) class SocialAccountAdmin(ModelAdmin): pass - admin.site.unregister(SocialToken) - @admin.register(SocialToken) class SocialTokenAdmin(ModelAdmin): pass - admin.site.unregister(SocialApp) - @admin.register(SocialApp) class SocialAppAdmin(ModelAdmin): pass - admin.site.unregister(Site) - @admin.register(Site) class SiteAdmin(ModelAdmin): pass From 08f419a448ddcf914c7fd13ec7102748024334d6 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Thu, 15 Feb 2024 21:16:21 +0100 Subject: [PATCH 07/18] Revert static configuration --- course_management/settings.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/course_management/settings.py b/course_management/settings.py index 3251c51..f17691e 100644 --- a/course_management/settings.py +++ b/course_management/settings.py @@ -152,12 +152,13 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.2/howto/static-files/ -STATIC_ROOT = BASE_DIR / "staticfiles" +STATIC_ROOT = BASE_DIR / "static" STATIC_URL = "static/" -STATICFILES_DIRS = [ - BASE_DIR / 'static', -] +# STATICFILES_DIRS = [ +# STATIC_ROOT, +# # Other directories here +# ] is_test = ("test" in sys.argv) or \ From d8db1490610e1f9b3d8607d7253927ece331dad0 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Thu, 15 Feb 2024 21:16:42 +0100 Subject: [PATCH 08/18] Fixed minor issues on course admin --- courses/admin.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/courses/admin.py b/courses/admin.py index a4bba1a..4b83227 100644 --- a/courses/admin.py +++ b/courses/admin.py @@ -101,11 +101,4 @@ class HomeworkAdmin(ModelAdmin): important_fields = ["course", "title", "due_date", "is_scored"] list_display = important_fields list_filter = important_fields - search_fields = important_fields - - -admin.site.register(Homework, HomeworkAdmin) - -admin.site.register(Course, CourseAdmin) - -admin.site.register(Project) + search_fields = important_fields \ No newline at end of file From 6e5fe70b944bf1fb2d7e0d163692b508633efaa9 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Thu, 15 Feb 2024 21:28:01 +0100 Subject: [PATCH 09/18] Removed tailwind styling --- course_management/settings.py | 14 +------------- static/css/style.css | 3 --- static/css/styles.css | 1 - tailwind.config.js | 7 ------- 4 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 static/css/style.css delete mode 100644 static/css/styles.css delete mode 100644 tailwind.config.js diff --git a/course_management/settings.py b/course_management/settings.py index f17691e..4478b4d 100644 --- a/course_management/settings.py +++ b/course_management/settings.py @@ -291,17 +291,5 @@ UNFOLD = { "SITE_HEADER": _("Course Management"), "SITE_TITLE": _("Course Management"), - "SITE_SYMBOL": "course", - "SHOW_HISTORY": False, - # "ENVIRONMENT": "formula.utils.environment_callback", - # "DASHBOARD_CALLBACK": "formula.views.dashboard_callback", - # "LOGIN": { - # "image": lambda request: static("images/login-bg.jpg"), - # }, - "STYLES": [ - lambda request: static("css/styles.css"), - ], - # "SCRIPTS": [ - # lambda request: static("js/chart.min.js"), - # ] + "SITE_SYMBOL": "school", } \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css deleted file mode 100644 index bd6213e..0000000 --- a/static/css/style.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; \ No newline at end of file diff --git a/static/css/styles.css b/static/css/styles.css deleted file mode 100644 index e213969..0000000 --- a/static/css/styles.css +++ /dev/null @@ -1 +0,0 @@ -/*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.m-0{margin:0}.mx-2{margin-left:.5rem;margin-right:.5rem}.mb-3{margin-bottom:.75rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.w-full{width:100%}.w-\[50\]{width:50}.w-\[50\%\]{width:50%}.w-\[10\]{width:10}.w-\[10\%\]{width:10%}.w-\[10px\]{width:10px}.w-32{width:8rem}.max-w-2xl{max-width:42rem}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-none{flex:none}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.text-center{text-align:center}.text-right{text-align:right}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-primary-600:focus{--tw-border-opacity:1;border-color:rgb(var(--color-primary-600)/var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-primary-300:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(var(--color-primary-300)/var(--tw-ring-opacity))}.group.errors .group-\[\.errors\]\:border-red-600{--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}.group.errors .group-\[\.errors\]\:focus\:ring-red-200:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(254 202 202/var(--tw-ring-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:bg-gray-900),:is(.dark :is(.dark .dark\:dark\:bg-gray-900)){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:focus\:border-primary-600:focus){--tw-border-opacity:1;border-color:rgb(var(--color-primary-600)/var(--tw-border-opacity))}:is(.dark .dark\:focus\:ring-primary-700:focus){--tw-ring-opacity:1;--tw-ring-color:rgb(var(--color-primary-700)/var(--tw-ring-opacity))}:is(.dark .dark\:focus\:ring-opacity-50:focus){--tw-ring-opacity:0.5}:is(.dark .group.errors .dark\:group-\[\.errors\]\:border-red-500){--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity))}:is(.dark .group.errors .dark\:group-\[\.errors\]\:focus\:ring-red-600\/40:focus){--tw-ring-color:#dc262666} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js deleted file mode 100644 index 9e7dca6..0000000 --- a/tailwind.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - content: ["./**/*.{html,py,js}"], - media: false, - darkMode: "class", - theme: {}, - plugins: [], -}; From d2c65ac349bc1febc0ee4d58a97b0c42dfaa362c Mon Sep 17 00:00:00 2001 From: Alexey Grigorev Date: Sat, 23 Mar 2024 11:44:49 +0100 Subject: [PATCH 10/18] pipfile updated --- Pipfile.lock | 313 ++++++++++++++++++++++++++------------------------- 1 file changed, 161 insertions(+), 152 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index d4143f0..13dc37d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2f6197836bcdc30f2dac7226136ba2f6a95329ef1adececf0f38e35428ca5c40" + "sha256": "96e2558b6d5e6b6ea3999f32a68e16d902cfcde800de9ae3f6f8d48da1864938" }, "pipfile-spec": 6, "requires": { @@ -19,11 +19,11 @@ "default": { "asgiref": { "hashes": [ - "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", - "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" + "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", + "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590" ], - "markers": "python_version >= '3.7'", - "version": "==3.7.2" + "markers": "python_version >= '3.8'", + "version": "==3.8.1" }, "certifi": { "hashes": [ @@ -205,40 +205,40 @@ }, "cryptography": { "hashes": [ - "sha256:087887e55e0b9c8724cf05361357875adb5c20dec27e5816b653492980d20380", - "sha256:09a77e5b2e8ca732a19a90c5bca2d124621a1edb5438c5daa2d2738bfeb02589", - "sha256:130c0f77022b2b9c99d8cebcdd834d81705f61c68e91ddd614ce74c657f8b3ea", - "sha256:141e2aa5ba100d3788c0ad7919b288f89d1fe015878b9659b307c9ef867d3a65", - "sha256:28cb2c41f131a5758d6ba6a0504150d644054fd9f3203a1e8e8d7ac3aea7f73a", - "sha256:2f9f14185962e6a04ab32d1abe34eae8a9001569ee4edb64d2304bf0d65c53f3", - "sha256:320948ab49883557a256eab46149df79435a22d2fefd6a66fe6946f1b9d9d008", - "sha256:36d4b7c4be6411f58f60d9ce555a73df8406d484ba12a63549c88bd64f7967f1", - "sha256:3b15c678f27d66d247132cbf13df2f75255627bcc9b6a570f7d2fd08e8c081d2", - "sha256:3dbd37e14ce795b4af61b89b037d4bc157f2cb23e676fa16932185a04dfbf635", - "sha256:4383b47f45b14459cab66048d384614019965ba6c1a1a141f11b5a551cace1b2", - "sha256:44c95c0e96b3cb628e8452ec060413a49002a247b2b9938989e23a2c8291fc90", - "sha256:4b063d3413f853e056161eb0c7724822a9740ad3caa24b8424d776cebf98e7ee", - "sha256:52ed9ebf8ac602385126c9a2fe951db36f2cb0c2538d22971487f89d0de4065a", - "sha256:55d1580e2d7e17f45d19d3b12098e352f3a37fe86d380bf45846ef257054b242", - "sha256:5ef9bc3d046ce83c4bbf4c25e1e0547b9c441c01d30922d812e887dc5f125c12", - "sha256:5fa82a26f92871eca593b53359c12ad7949772462f887c35edaf36f87953c0e2", - "sha256:61321672b3ac7aade25c40449ccedbc6db72c7f5f0fdf34def5e2f8b51ca530d", - "sha256:701171f825dcab90969596ce2af253143b93b08f1a716d4b2a9d2db5084ef7be", - "sha256:841ec8af7a8491ac76ec5a9522226e287187a3107e12b7d686ad354bb78facee", - "sha256:8a06641fb07d4e8f6c7dda4fc3f8871d327803ab6542e33831c7ccfdcb4d0ad6", - "sha256:8e88bb9eafbf6a4014d55fb222e7360eef53e613215085e65a13290577394529", - "sha256:a00aee5d1b6c20620161984f8ab2ab69134466c51f58c052c11b076715e72929", - "sha256:a047682d324ba56e61b7ea7c7299d51e61fd3bca7dad2ccc39b72bd0118d60a1", - "sha256:a7ef8dd0bf2e1d0a27042b231a3baac6883cdd5557036f5e8df7139255feaac6", - "sha256:ad28cff53f60d99a928dfcf1e861e0b2ceb2bc1f08a074fdd601b314e1cc9e0a", - "sha256:b9097a208875fc7bbeb1286d0125d90bdfed961f61f214d3f5be62cd4ed8a446", - "sha256:b97fe7d7991c25e6a31e5d5e795986b18fbbb3107b873d5f3ae6dc9a103278e9", - "sha256:e0ec52ba3c7f1b7d813cd52649a5b3ef1fc0d433219dc8c93827c57eab6cf888", - "sha256:ea2c3ffb662fec8bbbfce5602e2c159ff097a4631d96235fcf0fb00e59e3ece4", - "sha256:fa3dec4ba8fb6e662770b74f62f1a0c7d4e37e25b58b2bf2c1be4c95372b4a33", - "sha256:fbeb725c9dc799a574518109336acccaf1303c30d45c075c665c0793c2f79a7f" - ], - "version": "==42.0.2" + "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee", + "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576", + "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d", + "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30", + "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413", + "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb", + "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da", + "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4", + "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd", + "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc", + "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8", + "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1", + "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc", + "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e", + "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8", + "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940", + "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400", + "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7", + "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16", + "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278", + "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74", + "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec", + "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1", + "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2", + "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c", + "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922", + "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a", + "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6", + "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1", + "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e", + "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac", + "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7" + ], + "version": "==42.0.5" }, "defusedxml": { "hashes": [ @@ -258,11 +258,11 @@ }, "django": { "hashes": [ - "sha256:a2d4c4d4ea0b6f0895acde632071aff6400bfc331228fc978b05452a0ff3e9f1", - "sha256:b1260ed381b10a11753c73444408e19869f3241fc45c985cd55a30177c789d13" + "sha256:6e6ff3db2d8dd0c986b4eec8554c8e4f919b5c1ff62a5b4390c17aff2ed6e5c4", + "sha256:ddc24a0a8280a0430baa37aff11f28574720af05888c62b7cfe71d219f4599d3" ], "index": "pypi", - "version": "==4.2.10" + "version": "==4.2.11" }, "django-allauth": { "extras": [ @@ -274,6 +274,14 @@ "index": "pypi", "version": "==0.61.1" }, + "django-unfold": { + "hashes": [ + "sha256:7d1cf016c90801cce8dc9365dbc5dcdfc00828b6e01185eed5fd263897f71263", + "sha256:feecc0b526f6947663809911822517f5b9bb27c07799bd4b14cfafafc77c7e41" + ], + "index": "pypi", + "version": "==0.21.1" + }, "gunicorn": { "hashes": [ "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0", @@ -308,11 +316,11 @@ }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "psycopg2-binary": { "hashes": [ @@ -435,11 +443,11 @@ }, "requests-oauthlib": { "hashes": [ - "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", - "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", + "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.3.1" + "markers": "python_version >= '3.4'", + "version": "==2.0.0" }, "sqlparse": { "hashes": [ @@ -451,11 +459,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", + "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.10.0" }, "tzdata": { "hashes": [ @@ -467,11 +475,11 @@ }, "urllib3": { "hashes": [ - "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20", - "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], "markers": "python_version >= '3.8'", - "version": "==2.2.0" + "version": "==2.2.1" }, "whitenoise": { "hashes": [ @@ -485,11 +493,11 @@ "develop": { "anyio": { "hashes": [ - "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee", - "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f" + "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", + "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" ], "markers": "python_version >= '3.8'", - "version": "==4.2.0" + "version": "==4.3.0" }, "argon2-cffi": { "hashes": [ @@ -767,11 +775,11 @@ }, "comm": { "hashes": [ - "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a", - "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021" + "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", + "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3" ], "markers": "python_version >= '3.8'", - "version": "==0.2.1" + "version": "==0.2.2" }, "debugpy": { "hashes": [ @@ -857,19 +865,19 @@ }, "httpcore": { "hashes": [ - "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544", - "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2" + "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73", + "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022" ], "markers": "python_version >= '3.8'", - "version": "==1.0.3" + "version": "==1.0.4" }, "httpx": { "hashes": [ - "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf", - "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd" + "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", + "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5" ], "markers": "python_version >= '3.8'", - "version": "==0.26.0" + "version": "==0.27.0" }, "idna": { "hashes": [ @@ -881,11 +889,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", - "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" + "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2" ], "markers": "python_version < '3.10'", - "version": "==7.0.1" + "version": "==7.1.0" }, "iniconfig": { "hashes": [ @@ -897,11 +905,11 @@ }, "ipykernel": { "hashes": [ - "sha256:3bade28004e3ff624ed57974948116670604ac5f676d12339693f3142176d3f0", - "sha256:50384f5c577a260a1d53f1f59a828c7266d321c9b7d00d345693783f66616055" + "sha256:5aa086a4175b0229d4eca211e181fb473ea78ffd9869af36ba7694c947302a21", + "sha256:e14c250d1f9ea3989490225cc1a542781b095a18a19447fcf2b5eaf7d0ac5bd2" ], "markers": "python_version >= '3.8'", - "version": "==6.29.2" + "version": "==6.29.3" }, "ipython": { "hashes": [ @@ -944,10 +952,11 @@ }, "json5": { "hashes": [ - "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f", - "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02" + "sha256:0c638399421da959a20952782800e5c1a78c14e08e1dc9738fa10d8ec14d58c8", + "sha256:4ca101fd5c7cb47960c055ef8f4d0e31e15a7c6c48c3b6f1473fc83b6c462a13" ], - "version": "==0.9.14" + "markers": "python_version >= '3.8'", + "version": "==0.9.24" }, "jsonpointer": { "hashes": [ @@ -974,59 +983,59 @@ }, "jupyter-client": { "hashes": [ - "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7", - "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99" + "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f", + "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f" ], "markers": "python_version >= '3.8'", - "version": "==8.6.0" + "version": "==8.6.1" }, "jupyter-core": { "hashes": [ - "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7", - "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218" + "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", + "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9" ], "markers": "python_version >= '3.8'", - "version": "==5.7.1" + "version": "==5.7.2" }, "jupyter-events": { "hashes": [ - "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399", - "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf" + "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960", + "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22" ], "markers": "python_version >= '3.8'", - "version": "==0.9.0" + "version": "==0.10.0" }, "jupyter-lsp": { "hashes": [ - "sha256:256d24620542ae4bba04a50fc1f6ffe208093a07d8e697fea0a8d1b8ca1b7e5b", - "sha256:3b95229e4168355a8c91928057c1621ac3510ba98b2a925e82ebd77f078b1aa5" + "sha256:5e50033149344065348e688608f3c6d654ef06d9856b67655bd7b6bac9ee2d59", + "sha256:da61cb63a16b6dff5eac55c2699cc36eac975645adee02c41bdfc03bf4802e77" ], "markers": "python_version >= '3.8'", - "version": "==2.2.2" + "version": "==2.2.4" }, "jupyter-server": { "hashes": [ - "sha256:0edb626c94baa22809be1323f9770cf1c00a952b17097592e40d03e6a3951689", - "sha256:184a0f82809a8522777cfb6b760ab6f4b1bb398664c5860a27cec696cb884923" + "sha256:77b2b49c3831fbbfbdb5048cef4350d12946191f833a24e5f83e5f8f4803e97b", + "sha256:c80bfb049ea20053c3d9641c2add4848b38073bf79f1729cea1faed32fc1c78e" ], "markers": "python_version >= '3.8'", - "version": "==2.12.5" + "version": "==2.13.0" }, "jupyter-server-terminals": { "hashes": [ - "sha256:1b80c12765da979513c42c90215481bbc39bd8ae7c0350b4f85bc3eb58d0fa80", - "sha256:396b5ccc0881e550bf0ee7012c6ef1b53edbde69e67cab1d56e89711b46052e8" + "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", + "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269" ], "markers": "python_version >= '3.8'", - "version": "==0.5.2" + "version": "==0.5.3" }, "jupyterlab": { "hashes": [ - "sha256:8acc9f561729d8f32c14c294c397917cddfeeb13a5d46f811979b71b4911a9fd", - "sha256:fa3e8c18b804eac04e51ceebd9dd3dd396e08106816f0d09cc426799d7087632" + "sha256:3bc843382a25e1ab7bc31d9e39295a9f0463626692b7995597709c0ab236ab2c", + "sha256:c9ad75290cb10bfaff3624bf3fbb852319b4cce4c456613f8ebbaa98d03524db" ], "markers": "python_version >= '3.8'", - "version": "==4.1.1" + "version": "==4.1.5" }, "jupyterlab-pygments": { "hashes": [ @@ -1038,11 +1047,11 @@ }, "jupyterlab-server": { "hashes": [ - "sha256:846f125a8a19656611df5b03e5912c8393cea6900859baa64fa515eb64a8dc40", - "sha256:c48862519fded9b418c71645d85a49b2f0ec50d032ba8316738e9276046088c1" + "sha256:2098198e1e82e0db982440f9b5136175d73bea2cd42a6480aa6fd502cb23c4f9", + "sha256:eb645ecc8f9b24bac5decc7803b6d5363250e16ec5af814e516bc2c54dd88081" ], "markers": "python_version >= '3.8'", - "version": "==2.25.3" + "version": "==2.25.4" }, "markupsafe": { "hashes": [ @@ -1128,27 +1137,27 @@ }, "nbclient": { "hashes": [ - "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e", - "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15" + "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09", + "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f" ], "markers": "python_full_version >= '3.8.0'", - "version": "==0.9.0" + "version": "==0.10.0" }, "nbconvert": { "hashes": [ - "sha256:813e6553796362489ae572e39ba1bff978536192fb518e10826b0e8cadf03ec8", - "sha256:ad3dc865ea6e2768d31b7eb6c7ab3be014927216a5ece3ef276748dd809054c7" + "sha256:a6733b78ce3d47c3f85e504998495b07e6ea9cf9bf6ec1c98dda63ec6ad19142", + "sha256:ddeff14beeeedf3dd0bc506623e41e4507e551736de59df69a91f86700292b3b" ], "markers": "python_version >= '3.8'", - "version": "==7.16.0" + "version": "==7.16.3" }, "nbformat": { "hashes": [ - "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9", - "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192" + "sha256:60ed5e910ef7c6264b87d644f276b1b49e24011930deef54605188ddeb211685", + "sha256:d9476ca28676799af85385f409b49d95e199951477a159a576ef2a675151e5e8" ], "markers": "python_version >= '3.8'", - "version": "==5.9.2" + "version": "==5.10.3" }, "nest-asyncio": { "hashes": [ @@ -1160,11 +1169,11 @@ }, "notebook": { "hashes": [ - "sha256:99caf01ff166b1cc86355c9b37c1ba9bf566c1d7fc4ab57bb6f8f24e36c4260e", - "sha256:a8fa4ccb5e5fe220f29d9900337efd7752bc6f2efe004d6f320db01f7743adc9" + "sha256:efc2c80043909e0faa17fce9e9b37c059c03af0ec99a4d4db84cb21d9d2e936a", + "sha256:fc6c24b9aef18d0cd57157c9c47e95833b9b0bdc599652639acf0bdb61dc7d5f" ], "index": "pypi", - "version": "==7.1.0" + "version": "==7.1.2" }, "notebook-shim": { "hashes": [ @@ -1184,11 +1193,11 @@ }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pandocfilters": { "hashes": [ @@ -1300,11 +1309,11 @@ }, "pytest": { "hashes": [ - "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c", - "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6" + "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7", + "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044" ], "markers": "python_version >= '3.8'", - "version": "==8.0.0" + "version": "==8.1.1" }, "pytest-django": { "hashes": [ @@ -1316,11 +1325,11 @@ }, "python-dateutil": { "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" + "version": "==2.9.0.post0" }, "python-json-logger": { "hashes": [ @@ -1352,15 +1361,15 @@ }, "pywinpty": { "hashes": [ - "sha256:1617b729999eb6713590e17665052b1a6ae0ad76ee31e60b444147c5b6a35dca", - "sha256:189380469ca143d06e19e19ff3fba0fcefe8b4a8cc942140a6b863aed7eebb2d", - "sha256:21319cd1d7c8844fb2c970fb3a55a3db5543f112ff9cfcd623746b9c47501575", - "sha256:7520575b6546db23e693cbd865db2764097bd6d4ef5dc18c92555904cd62c3d4", - "sha256:8197de460ae8ebb7f5d1701dfa1b5df45b157bb832e92acba316305e18ca00dd", - "sha256:853985a8f48f4731a716653170cd735da36ffbdc79dcb4c7b7140bce11d8c722" + "sha256:2fd876b82ca750bb1333236ce98488c1be96b08f4f7647cfdf4129dfad83c2d4", + "sha256:61d420c2116c0212808d31625611b51caf621fe67f8a6377e2e8b617ea1c1f7d", + "sha256:697bff211fb5a6508fee2dc6ff174ce03f34a9a233df9d8b5fe9c8ce4d5eaf56", + "sha256:71cb613a9ee24174730ac7ae439fd179ca34ccb8c5349e8d7b72ab5dea2c6f4b", + "sha256:b96fb14698db1284db84ca38c79f15b4cfdc3172065b5137383910567591fa99", + "sha256:c34e32351a3313ddd0d7da23d27f835c860d32fe4ac814d372a3ea9594f41dde" ], "markers": "os_name == 'nt'", - "version": "==2.0.12" + "version": "==2.0.13" }, "pyyaml": { "hashes": [ @@ -1520,11 +1529,11 @@ }, "referencing": { "hashes": [ - "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5", - "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7" + "sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844", + "sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4" ], "markers": "python_version >= '3.8'", - "version": "==0.33.0" + "version": "==0.34.0" }, "requests": { "hashes": [ @@ -1689,11 +1698,11 @@ }, "sniffio": { "hashes": [ - "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101", - "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384" + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.3.1" }, "soupsieve": { "hashes": [ @@ -1718,11 +1727,11 @@ }, "terminado": { "hashes": [ - "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded", - "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e" + "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", + "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e" ], "markers": "python_version >= '3.8'", - "version": "==0.18.0" + "version": "==0.18.1" }, "tinycss2": { "hashes": [ @@ -1759,27 +1768,27 @@ }, "traitlets": { "hashes": [ - "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74", - "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e" + "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9", + "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80" ], "markers": "python_version >= '3.8'", - "version": "==5.14.1" + "version": "==5.14.2" }, "types-python-dateutil": { "hashes": [ - "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f", - "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2" + "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202", + "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b" ], "markers": "python_version >= '3.8'", - "version": "==2.8.19.20240106" + "version": "==2.9.0.20240316" }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", + "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.10.0" }, "uri-template": { "hashes": [ @@ -1790,11 +1799,11 @@ }, "urllib3": { "hashes": [ - "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20", - "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224" + "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", + "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" ], "markers": "python_version >= '3.8'", - "version": "==2.2.0" + "version": "==2.2.1" }, "wcwidth": { "hashes": [ @@ -1827,11 +1836,11 @@ }, "zipp": { "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b", + "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715" ], "markers": "python_version >= '3.8'", - "version": "==3.17.0" + "version": "==3.18.1" } } } From 7a70996e1503cd7ff464bd557e6a36147b9ec4e9 Mon Sep 17 00:00:00 2001 From: Alexey Grigorev Date: Sat, 23 Mar 2024 11:55:10 +0100 Subject: [PATCH 11/18] removed the account admin and modified the titles for the course admin --- accounts/admin.py | 51 ----------------------------------------------- courses/admin.py | 26 +++++++----------------- 2 files changed, 7 insertions(+), 70 deletions(-) diff --git a/accounts/admin.py b/accounts/admin.py index 3c7cb21..e69de29 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -1,51 +0,0 @@ -from django.contrib import admin -from unfold.admin import ModelAdmin -from django.contrib.auth.models import Group - -# Register your models here. -from allauth.account.models import EmailAddress -from allauth.account.admin import EmailAddressAdmin -from allauth.socialaccount.models import SocialAccount, SocialToken, SocialApp -from allauth.socialaccount.admin import ( - SocialAccountAdmin, - SocialTokenAdmin, - SocialAppAdmin, -) -from django.contrib.sites.admin import SiteAdmin -from django.contrib.sites.models import Site - -admin.site.unregister(Group) - -@admin.register(Group) -class GroupAdmin(ModelAdmin): - pass - -admin.site.unregister(EmailAddress) - -@admin.register(EmailAddress) -class EmailAddressAdmin(ModelAdmin): - pass - -admin.site.unregister(SocialAccount) - -@admin.register(SocialAccount) -class SocialAccountAdmin(ModelAdmin): - pass - -admin.site.unregister(SocialToken) - -@admin.register(SocialToken) -class SocialTokenAdmin(ModelAdmin): - pass - -admin.site.unregister(SocialApp) - -@admin.register(SocialApp) -class SocialAppAdmin(ModelAdmin): - pass - -admin.site.unregister(Site) - -@admin.register(Site) -class SiteAdmin(ModelAdmin): - pass diff --git a/courses/admin.py b/courses/admin.py index 52756a3..2edd518 100644 --- a/courses/admin.py +++ b/courses/admin.py @@ -75,10 +75,8 @@ def set_most_popular_as_correct(modeladmin, request, queryset): class HomeworkAdmin(ModelAdmin): inlines = [QuestionInline] actions = [score_selected_homeworks, set_most_popular_as_correct] - important_fields = ["course", "title", "due_date", "is_scored"] - list_display = important_fields - list_filter = important_fields - search_fields = important_fields + list_display = ["title", "course", "due_date", "is_scored"] + list_filter = ["course__slug"] class CriteriaForm(forms.ModelForm): @@ -114,10 +112,7 @@ def update_leaderboard_admin(modeladmin, request, queryset): class CourseAdmin(ModelAdmin): actions = [update_leaderboard_admin] inlines = [CriteriaInline] - important_fields = ["title", "social_media_hashtag"] - list_display = important_fields - list_filter = important_fields - search_fields = important_fields + list_display = ["title"] def assign_peer_reviews_for_project_admin( @@ -143,17 +138,10 @@ def assign_peer_reviews_for_project_admin( @admin.register(Project) class ProjectAdmin(ModelAdmin): actions = [assign_peer_reviews_for_project_admin] - important_fields = [ - "course", - "title", - "submission_due_date", - "learning_in_public_cap_project", - "peer_review_due_date", - "state", - ] - list_display = important_fields - list_filter = important_fields - search_fields = important_fields + + list_display = ["title", "course", "state"] + list_filter = ["course__slug"] + @admin.register(ReviewCriteria) From 75df497dd5de36d719e1a0da3ac962b4f6d8c819 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Wed, 27 Mar 2024 22:48:13 +0000 Subject: [PATCH 12/18] Added instructor to Course model --- courses/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/courses/models.py b/courses/models.py index f5233c5..6c60858 100644 --- a/courses/models.py +++ b/courses/models.py @@ -14,9 +14,9 @@ class Course(models.Model): + instructor = models.ForeignKey(User, on_delete=models.CASCADE, related_name="courses_taught") slug = models.SlugField(unique=True, blank=False) title = models.CharField(max_length=200) - description = models.TextField() students = models.ManyToManyField( User, through="Enrollment", related_name="courses_enrolled" From 61f73eca04a8c829103bfcff5f156a9873a395de Mon Sep 17 00:00:00 2001 From: Mohammed Date: Wed, 27 Mar 2024 22:48:53 +0000 Subject: [PATCH 13/18] Added Access control for admins / course instructors --- courses/admin.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/courses/admin.py b/courses/admin.py index 2edd518..46d0a0f 100644 --- a/courses/admin.py +++ b/courses/admin.py @@ -77,6 +77,14 @@ class HomeworkAdmin(ModelAdmin): actions = [score_selected_homeworks, set_most_popular_as_correct] list_display = ["title", "course", "due_date", "is_scored"] list_filter = ["course__slug"] + + def formfield_for_foreignkey(self, db_field, request, obj=None, **kwargs): + kwargs = handled_course_choices(db_field, kwargs, request) + return super().formfield_for_foreignkey(db_field, request, **kwargs) + + def get_queryset(self, request): + qs = super().get_queryset(request) + return get_queryset(request, qs, filter_field='course__instructor') class CriteriaForm(forms.ModelForm): @@ -113,7 +121,14 @@ class CourseAdmin(ModelAdmin): actions = [update_leaderboard_admin] inlines = [CriteriaInline] list_display = ["title"] + + def get_form(self, request, obj=None, **kwargs): + form = super().get_form(request, obj, **kwargs) + return get_form(request, form) + def get_queryset(self, request): + qs = super().get_queryset(request) + return get_queryset(request, qs) def assign_peer_reviews_for_project_admin( modeladmin, request, queryset @@ -142,8 +157,44 @@ class ProjectAdmin(ModelAdmin): list_display = ["title", "course", "state"] list_filter = ["course__slug"] + def get_queryset(self, request): + qs = super().get_queryset(request) + return get_queryset(request, qs, filter_field='course__instructor') + + def formfield_for_foreignkey(self, db_field, request, obj=None, **kwargs): + kwargs = handled_course_choices(db_field, kwargs, request) + return super().formfield_for_foreignkey(db_field, request, **kwargs) @admin.register(ReviewCriteria) class ReviewCriteriaAdmin(ModelAdmin): - pass + + def get_queryset(self, request): + qs = super().get_queryset(request) + return get_queryset(request, qs, filter_field='course__instructor') + + def formfield_for_foreignkey(self, db_field, request, obj=None, **kwargs): + kwargs = handled_course_choices(db_field, kwargs, request) + return super().formfield_for_foreignkey(db_field, request, **kwargs) + +def get_queryset(request, qs, filter_field="instructor"): + if request.user.is_superuser: + return qs + else: + return qs.filter(**{filter_field: request.user}) + + +def get_form(request, form): + if not request.user.is_superuser: + form.base_fields["instructor"].initial = request.user + form.base_fields["instructor"].widget = forms.HiddenInput() + return form + +def handled_course_choices(db_field, kwargs, request): + if db_field.name == "course": + kwargs["queryset"] = ( + Course.objects.all() + if request.user.is_superuser + else Course.objects.filter(instructor=request.user) + ) + return kwargs From 048c5cdaa4f861c5d90e5fec5b783fcd3037a4d2 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sun, 14 Apr 2024 14:48:37 +0100 Subject: [PATCH 14/18] Added instructor field to course model --- courses/models/course.py | 1 + 1 file changed, 1 insertion(+) diff --git a/courses/models/course.py b/courses/models/course.py index 996c8e7..239d819 100644 --- a/courses/models/course.py +++ b/courses/models/course.py @@ -13,6 +13,7 @@ class Course(models.Model): + instructor = models.ForeignKey(User, on_delete=models.CASCADE, related_name="courses_taught") slug = models.SlugField(unique=True, blank=False) title = models.CharField(max_length=200) From 4272fad4b57c17c01f1e1e35afb673230b84b097 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Sun, 14 Apr 2024 14:50:14 +0100 Subject: [PATCH 15/18] Updated course instructor field to manytomany field --- courses/models/course.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/courses/models/course.py b/courses/models/course.py index 239d819..5303e92 100644 --- a/courses/models/course.py +++ b/courses/models/course.py @@ -13,7 +13,7 @@ class Course(models.Model): - instructor = models.ForeignKey(User, on_delete=models.CASCADE, related_name="courses_taught") + instructor = models.ManyToManyField(User, through="Instructor", related_name="courses_taught") slug = models.SlugField(unique=True, blank=False) title = models.CharField(max_length=200) From 150a71a4752785c1018eac5a44d339010d374bd4 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Thu, 27 Jun 2024 16:05:32 +0100 Subject: [PATCH 16/18] Used ForeignKey instead of ManyToManyField --- courses/models/course.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/courses/models/course.py b/courses/models/course.py index 97f2ab9..71313ab 100644 --- a/courses/models/course.py +++ b/courses/models/course.py @@ -12,7 +12,7 @@ class Course(models.Model): - instructor = models.ManyToManyField(User, through="Instructor", related_name="courses_taught") + instructor = models.ForeignKey(User, on_delete=models.CASCADE, related_name="courses_teaching") slug = models.SlugField(unique=True, blank=False) title = models.CharField(max_length=200) From 32ad8345b5edc6eeca0eabac82a021d6dd83ac58 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Tue, 3 Dec 2024 21:03:50 +0100 Subject: [PATCH 17/18] Added instructor add field migration --- courses/migrations/0019_course_instructor.py | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 courses/migrations/0019_course_instructor.py diff --git a/courses/migrations/0019_course_instructor.py b/courses/migrations/0019_course_instructor.py new file mode 100644 index 0000000..265cf1a --- /dev/null +++ b/courses/migrations/0019_course_instructor.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.14 on 2024-12-03 19:49 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("courses", "0018_course_finished"), + ] + + operations = [ + migrations.AddField( + model_name="course", + name="instructor", + field=models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.CASCADE, + related_name="courses_teaching", + to=settings.AUTH_USER_MODEL, + ), + preserve_default=False, + ), + ] From 8f7bbe98fbf125cc8d89325f956a60ae2a70dda0 Mon Sep 17 00:00:00 2001 From: Mohammed Date: Tue, 3 Dec 2024 21:04:04 +0100 Subject: [PATCH 18/18] Fixed add new user from admin issue --- accounts/admin.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/accounts/admin.py b/accounts/admin.py index 79b8cc4..51ecfbc 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -2,13 +2,18 @@ from django import forms from django.contrib import admin - +from unfold.admin import ModelAdmin +from django.contrib.auth.admin import UserAdmin from .models import CustomUser, Token +from unfold.forms import UserCreationForm, AdminPasswordChangeForm, UserChangeForm -class CustomUserAdmin(admin.ModelAdmin): +class CustomUserAdmin(UserAdmin, ModelAdmin): search_fields = ["email"] change_form_template = 'loginas/change_form.html' + form = UserChangeForm + add_form = UserCreationForm + change_password_form = AdminPasswordChangeForm admin.site.register(CustomUser, CustomUserAdmin)