summaryrefslogtreecommitdiff
path: root/app/classes
diff options
context:
space:
mode:
Diffstat (limited to 'app/classes')
-rw-r--r--app/classes/__init__.py0
-rw-r--r--app/classes/admin.py45
-rw-r--r--app/classes/migrations/0001_initial.py57
-rw-r--r--app/classes/migrations/0002_alter_class_requires.py18
-rw-r--r--app/classes/migrations/0003_auto_20220109_2043.py25
-rw-r--r--app/classes/migrations/0004_rename_name_class_title.py18
-rw-r--r--app/classes/migrations/0005_auto_20220109_2100.py23
-rw-r--r--app/classes/migrations/0006_auto_20220109_2104.py28
-rw-r--r--app/classes/migrations/0007_session_status.py18
-rw-r--r--app/classes/migrations/0008_class_subtitle.py19
-rw-r--r--app/classes/migrations/__init__.py0
-rw-r--r--app/classes/models.py96
-rw-r--r--app/classes/templates/classes/class_detail.html11
-rw-r--r--app/classes/templates/classes/class_list.html43
-rw-r--r--app/classes/urls.py24
-rw-r--r--app/classes/views.py20
16 files changed, 445 insertions, 0 deletions
diff --git a/app/classes/__init__.py b/app/classes/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/classes/__init__.py
diff --git a/app/classes/admin.py b/app/classes/admin.py
new file mode 100644
index 0000000..5fcca4b
--- /dev/null
+++ b/app/classes/admin.py
@@ -0,0 +1,45 @@
+from django.contrib import admin
+from django import forms
+from django.contrib.gis.admin import OSMGeoAdmin
+from django.contrib.contenttypes.admin import GenericStackedInline
+
+from utils.widgets import AdminImageWidget, LGEntryForm
+from .models import Class, Session, ClassMedia
+
+
+@admin.register(Class)
+class ClassAdmin(admin.ModelAdmin):
+ list_display = ('title', 'session')
+ search_fields = ['title', 'description']
+ prepopulated_fields = {"slug": ('title',)}
+ list_filter = ('session',)
+ filter_horizontal = ('uploads',)
+
+ class Media:
+ js = ('image-loader.js', 'product-loader.js', 'next-prev-links.js')
+ css = {
+ "all": ("my_styles.css",)
+ }
+
+
+@admin.register(Session)
+class SessionAdmin(admin.ModelAdmin):
+ list_display = ('title','date_start','date_end' )
+ prepopulated_fields = {"slug": ('title',)}
+
+ class Media:
+ js = ('image-loader.js', 'product-loader.js', 'next-prev-links.js')
+ css = {
+ "all": ("my_styles.css",)
+ }
+
+
+@admin.register(ClassMedia)
+class ClassMediaAdmin(admin.ModelAdmin):
+ list_display = ('title','file' )
+
+ class Media:
+ js = ('image-loader.js', 'product-loader.js', 'next-prev-links.js')
+ css = {
+ "all": ("my_styles.css",)
+ }
diff --git a/app/classes/migrations/0001_initial.py b/app/classes/migrations/0001_initial.py
new file mode 100644
index 0000000..b533aaf
--- /dev/null
+++ b/app/classes/migrations/0001_initial.py
@@ -0,0 +1,57 @@
+# Generated by Django 3.2.8 on 2022-01-09 19:25
+
+import classes.models
+import datetime
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='ClassMedia',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('date_created', models.DateTimeField(default=datetime.datetime.now)),
+ ('file', models.FileField(blank=True, null=True, upload_to=classes.models.get_upload_path)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Session',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('date_start', models.DateField(verbose_name='Start Date')),
+ ('date_end', models.DateField(verbose_name='End Date')),
+ ('slug', models.SlugField()),
+ ],
+ options={
+ 'ordering': ('-date_start',),
+ 'get_latest_by': 'date_start',
+ },
+ ),
+ migrations.CreateModel(
+ name='Class',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=200)),
+ ('description', models.TextField()),
+ ('requires', models.TextField(verbose_name='If previous classwork is required, list prerequisites here')),
+ ('slug', models.SlugField()),
+ ('date_created', models.DateTimeField(default=datetime.datetime.now)),
+ ('session', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='classes.session')),
+ ('uploads', models.ManyToManyField(blank=True, to='classes.ClassMedia')),
+ ],
+ options={
+ 'ordering': ('-date_created',),
+ 'get_latest_by': 'date_created',
+ },
+ ),
+ ]
diff --git a/app/classes/migrations/0002_alter_class_requires.py b/app/classes/migrations/0002_alter_class_requires.py
new file mode 100644
index 0000000..8febb99
--- /dev/null
+++ b/app/classes/migrations/0002_alter_class_requires.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.8 on 2022-01-09 19:32
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='class',
+ name='requires',
+ field=models.TextField(blank=True, null=True, verbose_name='If previous classwork is required, list prerequisites here'),
+ ),
+ ]
diff --git a/app/classes/migrations/0003_auto_20220109_2043.py b/app/classes/migrations/0003_auto_20220109_2043.py
new file mode 100644
index 0000000..cd25dcd
--- /dev/null
+++ b/app/classes/migrations/0003_auto_20220109_2043.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.2.8 on 2022-01-09 20:43
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0002_alter_class_requires'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='class',
+ name='number_of_classes',
+ field=models.IntegerField(default=8),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='class',
+ name='price',
+ field=models.FloatField(default=225),
+ preserve_default=False,
+ ),
+ ]
diff --git a/app/classes/migrations/0004_rename_name_class_title.py b/app/classes/migrations/0004_rename_name_class_title.py
new file mode 100644
index 0000000..00ac456
--- /dev/null
+++ b/app/classes/migrations/0004_rename_name_class_title.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.8 on 2022-01-09 20:49
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0003_auto_20220109_2043'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='class',
+ old_name='name',
+ new_name='title',
+ ),
+ ]
diff --git a/app/classes/migrations/0005_auto_20220109_2100.py b/app/classes/migrations/0005_auto_20220109_2100.py
new file mode 100644
index 0000000..b5bd825
--- /dev/null
+++ b/app/classes/migrations/0005_auto_20220109_2100.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.2.8 on 2022-01-09 21:00
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0004_rename_name_class_title'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='classmedia',
+ old_name='name',
+ new_name='title',
+ ),
+ migrations.RenameField(
+ model_name='session',
+ old_name='name',
+ new_name='title',
+ ),
+ ]
diff --git a/app/classes/migrations/0006_auto_20220109_2104.py b/app/classes/migrations/0006_auto_20220109_2104.py
new file mode 100644
index 0000000..d25ead2
--- /dev/null
+++ b/app/classes/migrations/0006_auto_20220109_2104.py
@@ -0,0 +1,28 @@
+# Generated by Django 3.2.8 on 2022-01-09 21:04
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0005_auto_20220109_2100'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='class',
+ name='class_days',
+ field=models.IntegerField(choices=[(0, 'Mon/Wed'), (1, 'Tue/Thur')], default=0),
+ ),
+ migrations.AddField(
+ model_name='session',
+ name='length',
+ field=models.PositiveIntegerField(blank=True, null=True),
+ ),
+ migrations.AlterField(
+ model_name='class',
+ name='number_of_classes',
+ field=models.IntegerField(blank=True, null=True),
+ ),
+ ]
diff --git a/app/classes/migrations/0007_session_status.py b/app/classes/migrations/0007_session_status.py
new file mode 100644
index 0000000..d01d944
--- /dev/null
+++ b/app/classes/migrations/0007_session_status.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.8 on 2022-01-09 21:17
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0006_auto_20220109_2104'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='session',
+ name='status',
+ field=models.IntegerField(choices=[(0, 'Open'), (1, 'Closed')], default=0),
+ ),
+ ]
diff --git a/app/classes/migrations/0008_class_subtitle.py b/app/classes/migrations/0008_class_subtitle.py
new file mode 100644
index 0000000..1d572b0
--- /dev/null
+++ b/app/classes/migrations/0008_class_subtitle.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.8 on 2022-01-09 22:10
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('classes', '0007_session_status'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='class',
+ name='subtitle',
+ field=models.CharField(default='some text', max_length=200),
+ preserve_default=False,
+ ),
+ ]
diff --git a/app/classes/migrations/__init__.py b/app/classes/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/classes/migrations/__init__.py
diff --git a/app/classes/models.py b/app/classes/models.py
new file mode 100644
index 0000000..b10c863
--- /dev/null
+++ b/app/classes/models.py
@@ -0,0 +1,96 @@
+import datetime
+import os
+
+from django.dispatch import receiver
+from django.contrib.gis.db import models
+from django.db.models.signals import post_save
+from django.contrib.contenttypes.fields import GenericRelation, GenericForeignKey
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.sites.models import Site
+from django.urls import reverse
+from django.utils.functional import cached_property
+from django.apps import apps
+from django.conf import settings
+from django.contrib.sitemaps import Sitemap
+from django import forms
+
+import urllib.request
+import urllib.parse
+import urllib.error
+from django_gravatar.helpers import get_gravatar_url, has_gravatar, calculate_gravatar_hash
+from django_comments.signals import comment_was_posted
+from django_comments.models import Comment
+from django_comments.moderation import CommentModerator, moderator
+
+from taggit.managers import TaggableManager
+
+from utils.util import render_images, render_products, parse_video, markdown_to_html, extract_main_image
+
+
+def get_upload_path(self, filename):
+ return "files/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)
+
+
+class Session(models.Model):
+ title = models.CharField(max_length=200)
+ date_start = models.DateField('Start Date')
+ date_end = models.DateField('End Date')
+ slug = models.SlugField()
+ length = models.PositiveIntegerField(blank=True, null=True)
+ STATUS = (
+ (0, 'Open'),
+ (1, 'Closed'),
+ )
+ status = models.IntegerField(choices=STATUS, default=0)
+
+ class Meta:
+ ordering = ('-date_start',)
+ get_latest_by = 'date_start'
+
+ def __str__(self):
+ return self.title
+
+ def get_absolute_url(self):
+ return reverse('classes:session-detail', kwargs={"year": self.start_date.year, "month": self.start_date.strftime("%m"), "slug": self.slug})
+
+ # save length from date
+
+
+class ClassMedia(models.Model):
+ title = models.CharField(max_length=200)
+ date_created = models.DateTimeField(default=datetime.datetime.now)
+ file = models.FileField(blank=True, null=True, upload_to=get_upload_path)
+
+ def __str__(self):
+ return self.title
+
+
+class Class(models.Model):
+ title = models.CharField(max_length=200)
+ subtitle = models.CharField(max_length=200)
+ description = models.TextField()
+ requires = models.TextField('If previous classwork is required, list prerequisites here', null=True, blank=True,)
+ session = models.ForeignKey(Session, blank=True, null=True, on_delete=models.SET_NULL)
+ slug = models.SlugField()
+ uploads = models.ManyToManyField(ClassMedia, blank=True)
+ date_created = models.DateTimeField(default=datetime.datetime.now)
+ number_of_classes = models.IntegerField(blank=True, null=True)
+ CLASS_DAYS = (
+ (0, 'Mon/Wed'),
+ (1, 'Tue/Thur'),
+ )
+ class_days = models.IntegerField(choices=CLASS_DAYS, default=0)
+ price = models.FloatField()
+
+ class Meta:
+ ordering = ('-date_created',)
+ get_latest_by = 'date_created'
+
+ def __str__(self):
+ return self.title
+
+ def get_absolute_url(self):
+ return reverse('classes:detail', kwargs={"slug": self.slug})
+
+ def save(self, *args, **kwargs):
+ super(Class, self).save(*args, **kwargs)
diff --git a/app/classes/templates/classes/class_detail.html b/app/classes/templates/classes/class_detail.html
new file mode 100644
index 0000000..50ae63f
--- /dev/null
+++ b/app/classes/templates/classes/class_detail.html
@@ -0,0 +1,11 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{% block primary %}
+<main>
+<article>
+ <h2><a href="{{object.get_absolute_url}}">{{object.title|widont|smartypants}}</a></h2>
+ <h4>{{object.description|safe|widont|smartypants}}</h4>
+
+</article>
+</main>
+{% endblock %}
diff --git a/app/classes/templates/classes/class_list.html b/app/classes/templates/classes/class_list.html
new file mode 100644
index 0000000..fa1267c
--- /dev/null
+++ b/app/classes/templates/classes/class_list.html
@@ -0,0 +1,43 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{% load get_next %}
+{% load html5_datetime %}
+{% load pagination_tags %}
+{% block breadcrumbs %}{% include "lib/breadcrumbs.html" with breadcrumbs=breadcrumbs %}{% endblock %}
+{% block primary %}
+<main role="main" class="archive-wrapper">
+ <div class="archive-intro">
+ <h2 class="archive-hed">Classes</h2>
+ <p>More information coming soon.</p>
+ </div>
+ {% comment %}
+ {% autopaginate object_list 24 %}
+ <ul class="archive-list">{% for object in object_list %}
+ <li class="h-entry hentry archive-list-card" itemscope itemType="http://schema.org/Article">
+ {% if object.featured_image %}<a href="{{object.get_absolute_url}}" class="u-url">
+ <div class="circle-img-wrapper"><img src="{{object.featured_image.get_thumbnail_url}}" alt="{{object.featured_image.alt}}" class="u-photo" /></div>{%endif%}
+ <span class="date dt-published card-smcaps">{{object.pub_date|date:"F Y"}}</span>
+ <a href="{{object.get_absolute_url}}">
+ <h2 class="card-hed">{{object.title|safe|smartypants|widont}}</h2>
+ <p class="card-lede">{{object.subtitle}}</p>
+ <p class="p-summary">{{object.description}}</p>
+ {% if object.session.status == 0 %}
+ <p>Now Enrolling for {{object.session.title}} <br />({{object.number_of_classes}} classes every {{object.get_class_days_display}}, {{object.session.date_start}} - {{object.session.date_end}})</p>
+ {% else %}
+ <p>This class is not currently offered, but if you're interested please email me about setting up a future session.</p>
+ {% endif %}
+ {% if object.requires %}
+ <p>Prerequisites: {{object.requires}}</p>
+ {% endif %}
+ </a>
+ </li>
+ {%endfor%}</ul>
+ {%endcomment%}
+ </main>
+ {%comment%}
+ <nav aria-label="page navigation" class="pagination">
+ {% paginate %}
+ </nav>
+ {%endcomment%}
+</main>
+{% endblock %}
diff --git a/app/classes/urls.py b/app/classes/urls.py
new file mode 100644
index 0000000..ac9cce5
--- /dev/null
+++ b/app/classes/urls.py
@@ -0,0 +1,24 @@
+from django.urls import path, re_path
+
+from . import views
+
+app_name = "classes"
+
+urlpatterns = [
+ path(
+ r'<str:slug>',
+ views.ClassDetailView.as_view(),
+ name="detail"
+ ),
+ path(
+ r'',
+ views.ClassListView.as_view(),
+ {'page': 1},
+ name="list"
+ ),
+ path(
+ r'<page>/',
+ views.ClassListView.as_view(),
+ name="list"
+ ),
+]
diff --git a/app/classes/views.py b/app/classes/views.py
new file mode 100644
index 0000000..620e5db
--- /dev/null
+++ b/app/classes/views.py
@@ -0,0 +1,20 @@
+from utils.views import LuxDetailView
+from django.views.generic import DetailView, ListView
+from utils.views import PaginatedListView, LuxDetailView
+
+from .models import Class
+
+
+class ClassDetailView(LuxDetailView):
+ model = Class
+
+class ClassListView(PaginatedListView):
+ model = Class
+
+ def get_context_data(self, **kwargs):
+ '''
+ Add breadcrumb path
+ '''
+ context = super(ClassListView, self).get_context_data(**kwargs)
+ context['breadcrumbs'] = ("classes",)
+ return context