diff --git a/code/josh/Django/josh_lab01/grocery_list/__init__.py b/code/josh/Django/josh_lab01/grocery_list/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab01/grocery_list/admin.py b/code/josh/Django/josh_lab01/grocery_list/admin.py
new file mode 100644
index 00000000..2d99bcda
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from . models import GroceryItem
+
+admin.site.register(GroceryItem)
diff --git a/code/josh/Django/josh_lab01/grocery_list/apps.py b/code/josh/Django/josh_lab01/grocery_list/apps.py
new file mode 100644
index 00000000..0af6fbb4
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class GroceryListConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'grocery_list'
diff --git a/code/josh/Django/josh_lab01/grocery_list/migrations/0001_initial.py b/code/josh/Django/josh_lab01/grocery_list/migrations/0001_initial.py
new file mode 100644
index 00000000..146809b8
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/migrations/0001_initial.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.1.4 on 2022-12-21 18:40
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='GroceryItem',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('text_description', models.CharField(max_length=200)),
+ ('created_date', models.DateTimeField(verbose_name='created date')),
+ ('completed_date', models.DateTimeField(verbose_name='completed date')),
+ ('completed', models.BooleanField()),
+ ],
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab01/grocery_list/migrations/__init__.py b/code/josh/Django/josh_lab01/grocery_list/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab01/grocery_list/models.py b/code/josh/Django/josh_lab01/grocery_list/models.py
new file mode 100644
index 00000000..21cabf61
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/models.py
@@ -0,0 +1,11 @@
+from django.db import models
+
+
+class GroceryItem(models.Model):
+ text_description = models.CharField(max_length=50)
+ created_date = models.DateTimeField('created date', auto_now_add=True)
+ completed_date = models.DateTimeField('completed date')
+ completed = models.BooleanField()
+
+ def __str__(self):
+ return self.text_description
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab01/grocery_list/templates/grocery_list/index.html b/code/josh/Django/josh_lab01/grocery_list/templates/grocery_list/index.html
new file mode 100644
index 00000000..b42dc598
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/templates/grocery_list/index.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ Grocery List
+
+
+ Grocery List
+
+
+
+
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab01/grocery_list/tests.py b/code/josh/Django/josh_lab01/grocery_list/tests.py
new file mode 100644
index 00000000..7ce503c2
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/code/josh/Django/josh_lab01/grocery_list/urls.py b/code/josh/Django/josh_lab01/grocery_list/urls.py
new file mode 100644
index 00000000..a38aca7b
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/urls.py
@@ -0,0 +1,10 @@
+from django.urls import path
+
+from . import views
+
+app_name = 'grocery_list'
+urlpatterns = [
+ path('', views.index, name='index'),
+ path('complete/', views.complete, name='complete'),
+ path('delete/', views.delete, name='delete'),
+]
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab01/grocery_list/views.py b/code/josh/Django/josh_lab01/grocery_list/views.py
new file mode 100644
index 00000000..1bbe630c
--- /dev/null
+++ b/code/josh/Django/josh_lab01/grocery_list/views.py
@@ -0,0 +1,37 @@
+from django.shortcuts import render, get_object_or_404
+from django.http import HttpResponse, Http404, HttpResponseRedirect
+from django.template import loader
+from django.urls import reverse
+from datetime import datetime
+from . models import GroceryItem
+
+
+def index(request):
+ if request.method == 'POST':
+ form_data = request.POST
+ grocery_object = GroceryItem.objects.create(
+ text_description=form_data['text_description'],
+ created_date=datetime.now(),
+ completed_date=datetime.now(),
+ completed=False
+ )
+ return HttpResponseRedirect(reverse('grocery_list:index'))
+
+ else:
+ grocery_list = GroceryItem.objects.all()
+ context = {'grocery_list': grocery_list}
+ return render(request, 'grocery_list/index.html', context)
+
+def complete(request, id):
+ grocery_item = GroceryItem.objects.get(id=id)
+ if grocery_item.completed == False:
+ grocery_item.completed = True
+ else:
+ grocery_item.completed = False
+ grocery_item.save()
+ return HttpResponseRedirect(reverse('grocery_list:index'))
+
+def delete(request, id):
+ grocery_item = GroceryItem.objects.get(id=id)
+ grocery_item.delete()
+ return HttpResponseRedirect(reverse('grocery_list:index'))
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab01/josh_lab01/__init__.py b/code/josh/Django/josh_lab01/josh_lab01/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab01/josh_lab01/asgi.py b/code/josh/Django/josh_lab01/josh_lab01/asgi.py
new file mode 100644
index 00000000..1ff8320c
--- /dev/null
+++ b/code/josh/Django/josh_lab01/josh_lab01/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for josh_lab01 project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab01.settings')
+
+application = get_asgi_application()
diff --git a/code/josh/Django/josh_lab01/josh_lab01/settings.py b/code/josh/Django/josh_lab01/josh_lab01/settings.py
new file mode 100644
index 00000000..4ba5c1c3
--- /dev/null
+++ b/code/josh/Django/josh_lab01/josh_lab01/settings.py
@@ -0,0 +1,124 @@
+"""
+Django settings for josh_lab01 project.
+
+Generated by 'django-admin startproject' using Django 4.1.4.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/4.1/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'django-insecure--pt9g52qef4rs3k(zf0=0^qy^fi3@ro&otxem9%09yssx0$&mp'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'grocery_list.apps.GroceryListConfig',
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'josh_lab01.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'josh_lab01.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/4.1/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'America/Los_Angeles'
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/4.1/howto/static-files/
+
+STATIC_URL = 'static/'
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
diff --git a/code/josh/Django/josh_lab01/josh_lab01/urls.py b/code/josh/Django/josh_lab01/josh_lab01/urls.py
new file mode 100644
index 00000000..7e3e7abd
--- /dev/null
+++ b/code/josh/Django/josh_lab01/josh_lab01/urls.py
@@ -0,0 +1,22 @@
+"""josh_lab01 URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/4.1/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import include, path
+
+urlpatterns = [
+ path('grocery_list/', include('grocery_list.urls')),
+ path('admin/', admin.site.urls),
+]
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab01/josh_lab01/wsgi.py b/code/josh/Django/josh_lab01/josh_lab01/wsgi.py
new file mode 100644
index 00000000..26d47a17
--- /dev/null
+++ b/code/josh/Django/josh_lab01/josh_lab01/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for josh_lab01 project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab01.settings')
+
+application = get_wsgi_application()
diff --git a/code/josh/Django/josh_lab01/manage.py b/code/josh/Django/josh_lab01/manage.py
new file mode 100644
index 00000000..ddf68253
--- /dev/null
+++ b/code/josh/Django/josh_lab01/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab01.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/code/josh/Django/josh_lab02/josh_lab02/__init__.py b/code/josh/Django/josh_lab02/josh_lab02/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab02/josh_lab02/asgi.py b/code/josh/Django/josh_lab02/josh_lab02/asgi.py
new file mode 100644
index 00000000..97ebc9db
--- /dev/null
+++ b/code/josh/Django/josh_lab02/josh_lab02/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for josh_lab02 project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab02.settings')
+
+application = get_asgi_application()
diff --git a/code/josh/Django/josh_lab02/josh_lab02/settings.py b/code/josh/Django/josh_lab02/josh_lab02/settings.py
new file mode 100644
index 00000000..77fda85c
--- /dev/null
+++ b/code/josh/Django/josh_lab02/josh_lab02/settings.py
@@ -0,0 +1,124 @@
+"""
+Django settings for josh_lab02 project.
+
+Generated by 'django-admin startproject' using Django 4.1.4.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/4.1/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'django-insecure-z5wv*j!h*qv-omi_^)s6id+eu&$5@^i(s_gc-y3*98e=9!s@!^'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'url_shortener.apps.UrlShortenerConfig',
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'josh_lab02.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'josh_lab02.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/4.1/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/4.1/howto/static-files/
+
+STATIC_URL = 'static/'
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
diff --git a/code/josh/Django/josh_lab02/josh_lab02/urls.py b/code/josh/Django/josh_lab02/josh_lab02/urls.py
new file mode 100644
index 00000000..ce973753
--- /dev/null
+++ b/code/josh/Django/josh_lab02/josh_lab02/urls.py
@@ -0,0 +1,22 @@
+"""josh_lab02 URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/4.1/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import include, path
+
+urlpatterns = [
+ path('url_shortener/', include('url_shortener.urls')),
+ path('admin/', admin.site.urls),
+]
diff --git a/code/josh/Django/josh_lab02/josh_lab02/wsgi.py b/code/josh/Django/josh_lab02/josh_lab02/wsgi.py
new file mode 100644
index 00000000..b1aba64f
--- /dev/null
+++ b/code/josh/Django/josh_lab02/josh_lab02/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for josh_lab02 project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab02.settings')
+
+application = get_wsgi_application()
diff --git a/code/josh/Django/josh_lab02/manage.py b/code/josh/Django/josh_lab02/manage.py
new file mode 100644
index 00000000..68e14990
--- /dev/null
+++ b/code/josh/Django/josh_lab02/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab02.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/code/josh/Django/josh_lab02/url_shortener/__init__.py b/code/josh/Django/josh_lab02/url_shortener/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab02/url_shortener/admin.py b/code/josh/Django/josh_lab02/url_shortener/admin.py
new file mode 100644
index 00000000..aefbe40f
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from . models import UrlShortener
+
+admin.site.register(UrlShortener)
diff --git a/code/josh/Django/josh_lab02/url_shortener/apps.py b/code/josh/Django/josh_lab02/url_shortener/apps.py
new file mode 100644
index 00000000..f3e477d6
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class UrlShortenerConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'url_shortener'
diff --git a/code/josh/Django/josh_lab02/url_shortener/migrations/0001_initial.py b/code/josh/Django/josh_lab02/url_shortener/migrations/0001_initial.py
new file mode 100644
index 00000000..c9c1bff1
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/migrations/0001_initial.py
@@ -0,0 +1,22 @@
+# Generated by Django 4.1.4 on 2022-12-27 21:37
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='UrlShortener',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('long_url', models.CharField(max_length=200)),
+ ('short_code', models.CharField(max_length=200)),
+ ],
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab02/url_shortener/migrations/0002_alter_urlshortener_short_code.py b/code/josh/Django/josh_lab02/url_shortener/migrations/0002_alter_urlshortener_short_code.py
new file mode 100644
index 00000000..2e152aab
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/migrations/0002_alter_urlshortener_short_code.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.4 on 2022-12-28 18:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('url_shortener', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='urlshortener',
+ name='short_code',
+ field=models.CharField(max_length=20),
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab02/url_shortener/migrations/__init__.py b/code/josh/Django/josh_lab02/url_shortener/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab02/url_shortener/models.py b/code/josh/Django/josh_lab02/url_shortener/models.py
new file mode 100644
index 00000000..a1e5ed57
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/models.py
@@ -0,0 +1,8 @@
+from django.db import models
+
+class UrlShortener(models.Model):
+ long_url = models.CharField(max_length=200)
+ short_code = models.CharField(max_length=20)
+
+ def __str__(self):
+ return self.long_url
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab02/url_shortener/templates/url_shortener/index.html b/code/josh/Django/josh_lab02/url_shortener/templates/url_shortener/index.html
new file mode 100644
index 00000000..4aeb7a4e
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/templates/url_shortener/index.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ URL Shortener: Django Lab 02
+
+
+ Welcome to the URL Shortener!
+
+ {% for item in url_shortener %}
+ Original URL: {{ item.long_url }} Shortened URL: {{ item.short_code }}
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab02/url_shortener/tests.py b/code/josh/Django/josh_lab02/url_shortener/tests.py
new file mode 100644
index 00000000..7ce503c2
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/code/josh/Django/josh_lab02/url_shortener/urls.py b/code/josh/Django/josh_lab02/url_shortener/urls.py
new file mode 100644
index 00000000..1d873858
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/urls.py
@@ -0,0 +1,9 @@
+from django.urls import path
+
+from . import views
+
+app_name = 'url_shortener'
+urlpatterns = [
+ path('redirect/', views.redirect, name='redirect'),
+ path('', views.index, name='index'),
+]
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab02/url_shortener/views.py b/code/josh/Django/josh_lab02/url_shortener/views.py
new file mode 100644
index 00000000..a1d240e5
--- /dev/null
+++ b/code/josh/Django/josh_lab02/url_shortener/views.py
@@ -0,0 +1,30 @@
+import random
+from string import ascii_letters as letters, digits as digits
+from django.shortcuts import render
+from django.http import HttpResponseRedirect
+from django.urls import reverse
+from . models import UrlShortener
+
+
+def index(request):
+ if request.method == 'POST':
+ form_data = request.POST
+ all_characters = letters + digits
+ code = []
+ while len(code) < 10:
+ code.append(random.choice(all_characters))
+ code_join = "".join(code)
+ url = UrlShortener.objects.create(
+ long_url=form_data['long_url'],
+ short_code = code_join
+ )
+ return HttpResponseRedirect(reverse('url_shortener:index'))
+ else:
+ url = UrlShortener.objects.all()
+ context = {'url_shortener': url}
+ return render(request, 'url_shortener/index.html', context)
+
+
+def redirect(request, id):
+ url = UrlShortener.objects.get(id=id)
+ return HttpResponseRedirect(url.long_url)
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/josh_lab03/__init__.py b/code/josh/Django/josh_lab03/josh_lab03/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab03/josh_lab03/asgi.py b/code/josh/Django/josh_lab03/josh_lab03/asgi.py
new file mode 100644
index 00000000..cd9a5d1f
--- /dev/null
+++ b/code/josh/Django/josh_lab03/josh_lab03/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for josh_lab03 project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab03.settings')
+
+application = get_asgi_application()
diff --git a/code/josh/Django/josh_lab03/josh_lab03/settings.py b/code/josh/Django/josh_lab03/josh_lab03/settings.py
new file mode 100644
index 00000000..12cc4732
--- /dev/null
+++ b/code/josh/Django/josh_lab03/josh_lab03/settings.py
@@ -0,0 +1,130 @@
+"""
+Django settings for josh_lab03 project.
+
+Generated by 'django-admin startproject' using Django 4.1.4.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/4.1/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'django-insecure-7t94trcb@3=%u2t&_sxrfhm!l3wb!rr0=w1_-v$s6f1&8*=e!a'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'posts.apps.PostsConfig',
+ 'users.apps.UsersConfig',
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'josh_lab03.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [BASE_DIR / "templates"],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'josh_lab03.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/4.1/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_TZ = False
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/4.1/howto/static-files/
+
+STATIC_URL = 'static/'
+STATICFILES_DIRS = [BASE_DIR, "static/"]
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+# django_project/settings.py
+LOGIN_REDIRECT_URL = "home"
+LOGOUT_REDIRECT_URL = "home"
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/josh_lab03/urls.py b/code/josh/Django/josh_lab03/josh_lab03/urls.py
new file mode 100644
index 00000000..eaf91316
--- /dev/null
+++ b/code/josh/Django/josh_lab03/josh_lab03/urls.py
@@ -0,0 +1,26 @@
+"""josh_lab03 URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/4.1/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import include, path
+from django.views.generic.base import TemplateView
+
+urlpatterns = [
+ path('', TemplateView.as_view(template_name='home.html'), name='home'),
+ path("accounts/", include("django.contrib.auth.urls")),
+ path('posts/', include('posts.urls')),
+ path('users/', include('users.urls')),
+ path('admin/', admin.site.urls),
+]
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/josh_lab03/wsgi.py b/code/josh/Django/josh_lab03/josh_lab03/wsgi.py
new file mode 100644
index 00000000..77911ef0
--- /dev/null
+++ b/code/josh/Django/josh_lab03/josh_lab03/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for josh_lab03 project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab03.settings')
+
+application = get_wsgi_application()
diff --git a/code/josh/Django/josh_lab03/manage.py b/code/josh/Django/josh_lab03/manage.py
new file mode 100644
index 00000000..3ef961a9
--- /dev/null
+++ b/code/josh/Django/josh_lab03/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'josh_lab03.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/code/josh/Django/josh_lab03/posts/__init__.py b/code/josh/Django/josh_lab03/posts/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab03/posts/admin.py b/code/josh/Django/josh_lab03/posts/admin.py
new file mode 100644
index 00000000..b9a26f04
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from .models import Posts
+
+admin.site.register(Posts)
diff --git a/code/josh/Django/josh_lab03/posts/apps.py b/code/josh/Django/josh_lab03/posts/apps.py
new file mode 100644
index 00000000..b18ed0dc
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class PostsConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'posts'
diff --git a/code/josh/Django/josh_lab03/posts/migrations/0001_initial.py b/code/josh/Django/josh_lab03/posts/migrations/0001_initial.py
new file mode 100644
index 00000000..40e145b1
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/migrations/0001_initial.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.1.4 on 2022-12-28 22:18
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Posts',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('chirp', models.CharField(max_length=128)),
+ ],
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab03/posts/migrations/0002_posts_users.py b/code/josh/Django/josh_lab03/posts/migrations/0002_posts_users.py
new file mode 100644
index 00000000..254b7f23
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/migrations/0002_posts_users.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.1.4 on 2022-12-30 18:11
+
+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),
+ ('posts', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='posts',
+ name='users',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab03/posts/migrations/0003_posts_pub_date.py b/code/josh/Django/josh_lab03/posts/migrations/0003_posts_pub_date.py
new file mode 100644
index 00000000..d66dfd94
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/migrations/0003_posts_pub_date.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.4 on 2022-12-30 19:47
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('posts', '0002_posts_users'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='posts',
+ name='pub_date',
+ field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='date published'),
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab03/posts/migrations/__init__.py b/code/josh/Django/josh_lab03/posts/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab03/posts/models.py b/code/josh/Django/josh_lab03/posts/models.py
new file mode 100644
index 00000000..42517853
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/models.py
@@ -0,0 +1,11 @@
+from django.db import models
+from django.contrib.auth.models import User
+
+
+class Posts(models.Model):
+ chirp = models.CharField(max_length=128)
+ users = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
+ pub_date = models.DateTimeField('date published', auto_now_add=True, null=True)
+
+ def __str__(self):
+ return(f'{self.chirp}, {self.users}, {self.pub_date}')
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/posts/templates/posts/index.html b/code/josh/Django/josh_lab03/posts/templates/posts/index.html
new file mode 100644
index 00000000..447243b1
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/templates/posts/index.html
@@ -0,0 +1,18 @@
+{% extends 'base.html' %}
+{% block title %}Posts: Django Lab 03{% endblock %}
+{% block content %}
+
+
+
+{% for item in posts reversed %}
+
+{{ item.users }} says "{{ item.chirp }}" {{ item.pub_date }}
+
+{% endfor %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/posts/tests.py b/code/josh/Django/josh_lab03/posts/tests.py
new file mode 100644
index 00000000..7ce503c2
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/code/josh/Django/josh_lab03/posts/urls.py b/code/josh/Django/josh_lab03/posts/urls.py
new file mode 100644
index 00000000..e44af38e
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/urls.py
@@ -0,0 +1,8 @@
+from django.urls import path
+
+from . import views
+
+app_name = 'posts'
+urlpatterns = [
+ path('', views.index, name='index'),
+]
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/posts/views.py b/code/josh/Django/josh_lab03/posts/views.py
new file mode 100644
index 00000000..c2582918
--- /dev/null
+++ b/code/josh/Django/josh_lab03/posts/views.py
@@ -0,0 +1,22 @@
+from django.shortcuts import render
+from django.http import HttpResponseRedirect
+from django.urls import reverse
+from . models import Posts
+from django.contrib.auth.models import User
+
+def index(request):
+ if request.method == 'POST':
+ form_data = request.POST
+ user = User.objects.filter(username=request.user)
+ date = Posts.objects.all()
+ print(date)
+ post = Posts.objects.create(
+ chirp = form_data['chirp'],
+ users = user[0]
+ )
+ return HttpResponseRedirect(reverse('posts:index'))
+ else:
+ post = Posts.objects.all()
+ user = User.objects.filter(username=request.user)
+ context = {'posts': post}
+ return render(request, 'posts/index.html', context)
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/static/background_eggs.jpg b/code/josh/Django/josh_lab03/static/background_eggs.jpg
new file mode 100644
index 00000000..ead95a3e
Binary files /dev/null and b/code/josh/Django/josh_lab03/static/background_eggs.jpg differ
diff --git a/code/josh/Django/josh_lab03/static/styles.css b/code/josh/Django/josh_lab03/static/styles.css
new file mode 100644
index 00000000..e746dba1
--- /dev/null
+++ b/code/josh/Django/josh_lab03/static/styles.css
@@ -0,0 +1,54 @@
+body, html {
+ background-image: url('background_eggs.jpg');
+ background-size: cover;
+ background-attachment: fixed;
+ margin: auto;
+}
+
+.container {
+ display: grid;
+ grid-template-columns: 70vw;
+ grid-template-areas:
+ "header"
+ "nav"
+ "article"
+ "footer";
+ text-align: center;
+ justify-content: center;
+ margin: 5vw 0 5vw 0;
+ width: 100vw;
+}
+.container > * {
+ display: flex;
+ max-width: 95vw;
+ flex-flow: column wrap;
+ justify-content: center;
+ align-items: center;
+ align-content: center;
+}
+
+header {
+ grid-area: header;
+ font-family:Georgia, 'Times New Roman', Times, serif;
+ font-size: 10vw;
+
+}
+
+nav {
+ grid-area: nav;
+ flex-direction: row !important;
+}
+
+article {
+ grid-area: article;
+ border-style: solid;
+ border-width: 2px;
+ background-color: rgba(87, 188, 235, 0.801);
+ padding: 1vw;
+ font-size: 2vw;
+ margin: 0 1vw 0 1vw;
+}
+
+footer {
+ grid-area: footer;
+}
diff --git a/code/josh/Django/josh_lab03/templates/base.html b/code/josh/Django/josh_lab03/templates/base.html
new file mode 100644
index 00000000..4566bf26
--- /dev/null
+++ b/code/josh/Django/josh_lab03/templates/base.html
@@ -0,0 +1,25 @@
+
+{% load static %}
+
+
+
+
+
+
+ {% block title %}Django Auth Tutorial{% endblock %}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/templates/home.html b/code/josh/Django/josh_lab03/templates/home.html
new file mode 100644
index 00000000..f2ea9ab0
--- /dev/null
+++ b/code/josh/Django/josh_lab03/templates/home.html
@@ -0,0 +1,14 @@
+
+{% extends 'base.html' %}
+
+{% block title %}Home{% endblock %}
+
+{% block content %}
+{% if user.is_authenticated %}
+ Hi {{ user.username }}!
+ Log Out
+{% else %}
+ You are not logged in
+ Log In
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/templates/registration/login.html b/code/josh/Django/josh_lab03/templates/registration/login.html
new file mode 100644
index 00000000..3efaa307
--- /dev/null
+++ b/code/josh/Django/josh_lab03/templates/registration/login.html
@@ -0,0 +1,18 @@
+
+{% extends 'base.html' %}
+
+{% block title %}Login{% endblock %}
+
+{% block content %}
+Log In
+
+or
+
+{% endblock %}
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/templates/registration/signup.html b/code/josh/Django/josh_lab03/templates/registration/signup.html
new file mode 100644
index 00000000..e5dded06
--- /dev/null
+++ b/code/josh/Django/josh_lab03/templates/registration/signup.html
@@ -0,0 +1,13 @@
+
+{% extends "base.html" %}
+
+{% block title %}Sign Up{% endblock %}
+
+{% block content %}
+ Sign up
+
+{% endblock %}
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/users/__init__.py b/code/josh/Django/josh_lab03/users/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab03/users/admin.py b/code/josh/Django/josh_lab03/users/admin.py
new file mode 100644
index 00000000..387cdc37
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from .models import Users
+
+admin.site.register(Users)
diff --git a/code/josh/Django/josh_lab03/users/apps.py b/code/josh/Django/josh_lab03/users/apps.py
new file mode 100644
index 00000000..72b14010
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class UsersConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'users'
diff --git a/code/josh/Django/josh_lab03/users/migrations/0001_initial.py b/code/josh/Django/josh_lab03/users/migrations/0001_initial.py
new file mode 100644
index 00000000..b484fb64
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/migrations/0001_initial.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.1.4 on 2022-12-28 22:18
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Users',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('username', models.CharField(max_length=50)),
+ ],
+ ),
+ ]
diff --git a/code/josh/Django/josh_lab03/users/migrations/__init__.py b/code/josh/Django/josh_lab03/users/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/code/josh/Django/josh_lab03/users/models.py b/code/josh/Django/josh_lab03/users/models.py
new file mode 100644
index 00000000..e9647fba
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/models.py
@@ -0,0 +1,7 @@
+from django.db import models
+
+class Users(models.Model):
+ username = models.CharField(max_length=50)
+
+ def __str__(self):
+ return self.username
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/users/tests.py b/code/josh/Django/josh_lab03/users/tests.py
new file mode 100644
index 00000000..7ce503c2
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/code/josh/Django/josh_lab03/users/urls.py b/code/josh/Django/josh_lab03/users/urls.py
new file mode 100644
index 00000000..b85bc92d
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/urls.py
@@ -0,0 +1,7 @@
+from django.urls import path
+from .views import SignUpView
+
+app_name = 'users'
+urlpatterns = [
+ path("signup/", SignUpView.as_view(), name="signup"),
+]
\ No newline at end of file
diff --git a/code/josh/Django/josh_lab03/users/views.py b/code/josh/Django/josh_lab03/users/views.py
new file mode 100644
index 00000000..c227d7b7
--- /dev/null
+++ b/code/josh/Django/josh_lab03/users/views.py
@@ -0,0 +1,9 @@
+from django.contrib.auth.forms import UserCreationForm
+from django.urls import reverse_lazy
+from django.views import generic
+
+
+class SignUpView(generic.CreateView):
+ form_class = UserCreationForm
+ success_url = reverse_lazy("login")
+ template_name = "registration/signup.html"
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab01/index.html b/code/josh/javascript/josh_js_lab01/index.html
new file mode 100644
index 00000000..845f7c26
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab01/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ JavaScript Lab 01
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab01/lab01.js b/code/josh/javascript/josh_js_lab01/lab01.js
new file mode 100644
index 00000000..8eb8564c
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab01/lab01.js
@@ -0,0 +1,20 @@
+// Lab 1 - Unit Converter, Version 4
+
+// Creates a variable that stores user input of a distance as units
+let userDistance = prompt("What is the distance (ft, mi, m, km, yd or in)? ")
+// Typecasts user input to an integer for conversion
+userDistance = parseInt(userDistance)
+// Creates a variable that stores user input of a starting unit of measure
+const unitsInput = prompt("What are the input units (ft, mi, m, km, yd, or in)? ")
+// Creates a variable that stores the user's desired unit of measure as an output
+const unitsOutput = prompt("What are the output units (ft, mi, m, km, yd, or in)? ")
+// Creates a dictionary that stores units of measure as keys and numeric conversions as values
+conversion = {"ft": 0.3048, "mi": 1609.34, "m": 1, "km": 1000, "yd": 0.9144, "in": 0.0254}
+// Creates a variable that converts user input of distance to meters, according to user input of
+// desired starting units
+const newDistance = userDistance * conversion[unitsInput]
+// Creates a variable that converts meter conversion to user input of desired output units
+const newUnits = newDistance / conversion[unitsOutput]
+// Displays the conversion of user's inputs of distance and unit measure to user's desired unit
+// measureoutput
+alert(`${userDistance} ${unitsInput} is ${newUnits} ${unitsOutput}.`)
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab02/index.html b/code/josh/javascript/josh_js_lab02/index.html
new file mode 100644
index 00000000..94101559
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab02/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ JavaScript Lab 02
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab02/lab02.js b/code/josh/javascript/josh_js_lab02/lab02.js
new file mode 100644
index 00000000..7a4b6bc6
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab02/lab02.js
@@ -0,0 +1,111 @@
+// Lab 2: Number to Phrase
+// Convert a given number into its English representation. Handle numbers from 0-999.
+
+let number = prompt("Please enter a number from 0 to 999: ")
+number = parseInt(number)
+const numberListTo19 = {
+ 0: "",
+ 1: "one",
+ 2: "two",
+ 3: "three",
+ 4: "four",
+ 5: "five",
+ 6: "six",
+ 7: "seven",
+ 8: "eight",
+ 9: "nine",
+ 10: "ten",
+ 11: "eleven",
+ 12: "twelve",
+ 13: "thirteen",
+ 14: "fourteen",
+ 15: "fifteen",
+ 16: "sixteen",
+ 17: "seventeen",
+ 18: "eighteen",
+ 19: "nineteen"
+}
+const numberListForTeensOver100 = {
+ 11: "eleven",
+ 12: "twelve",
+ 13: "thirteen",
+ 14: "fourteen",
+ 15: "fifteen",
+ 16: "sixteen",
+ 17: "seventeen",
+ 18: "eighteen",
+ 19: "nineteen"
+}
+const numberListByTens = {
+ 20: "twenty",
+ 30: "thirty",
+ 40: "forty",
+ 50: "fifty",
+ 60: "sixty",
+ 70: "seventy",
+ 80: "eighty",
+ 90: "ninety"
+}
+const numberListByTensOver100 = {
+ 1: "ten",
+ 2: "twenty",
+ 3: "thirty",
+ 4: "forty",
+ 5: "fifty",
+ 6: "sixty",
+ 7: "seventy",
+ 8: "eighty",
+ 9: "ninety"
+}
+const tensPlaceNumberList = {
+ 0: "",
+ 2: "twenty-",
+ 3: "thirty-",
+ 4: "forty-",
+ 5: "fifty-",
+ 6: "sixty-",
+ 7: "seventy-",
+ 8: "eighty-",
+ 9: "ninety-"
+}
+const hundredsPlaceNumberList = {
+ 1: "one hundred",
+ 2: "two hundred",
+ 3: "three hundred",
+ 4: "four hundred",
+ 5: "five hundred",
+ 6: "six hundred",
+ 7: "seven hundred",
+ 8: "eight hundred",
+ 9: "nine hundred"
+}
+unitsPlace = number%10
+tensPlace = Math.floor(number/10)
+hundredsPlace = Math.floor(number/100)
+hundredsRemainder = Math.floor(number%100/10)
+unitsRemainder = number%100%10
+teensRemainder = number%100
+
+if (number < 0) {
+ alert("Your entry is invalid. You did not enter a number from 0 to 999.")
+} else if (number == 0) {
+ alert("0 is written out as zero.")
+} else if (number <= 19) {
+ alert(`${number} is written out as ${numberListTo19[number]}.`)
+} else if (number == 20 || number == 30 || number == 40 || number == 50 || number == 60 || number == 70 || number == 80 || number == 90) {
+ alert(`${number} is written out as ${numberListByTens[number]}.`)
+} else if (number >= 21 && number <= 99) {
+ alert(`${number} is written out as ${tensPlaceNumberList[tensPlace]}${numberListTo19[unitsPlace]}.`)
+} else if (number >= 100 && number <= 999) {
+ if (number == 100 || number == 200 || number == 300 || number == 400 || number == 500 || number == 600 || number == 700 || number == 800 || number == 900) {
+ alert(`${number} is written out as ${hundredsPlaceNumberList[hundredsPlace]}`)
+ } else if (unitsRemainder == 0) {
+ alert(`${number} is written out as ${hundredsPlaceNumberList[hundredsPlace]} ${numberListByTensOver100[hundredsRemainder]}`)
+ } else if (hundredsRemainder == 1) {
+ alert(`${number} is written out as ${hundredsPlaceNumberList[hundredsPlace]} ${numberListForTeensOver100[teensRemainder]}`)
+ } else {
+ alert(`${number} is written out as ${hundredsPlaceNumberList[hundredsPlace]} ${tensPlaceNumberList[hundredsRemainder]}${numberListTo19[unitsRemainder]}.`)
+ }
+} else {
+ alert("Your entry is invalid. You did not enter a number from 0 to 999.")
+}
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab03/index.html b/code/josh/javascript/josh_js_lab03/index.html
new file mode 100644
index 00000000..e53f1839
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab03/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ JavaScript Lab 03
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab03/lab03.js b/code/josh/javascript/josh_js_lab03/lab03.js
new file mode 100644
index 00000000..ef9b01d0
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab03/lab03.js
@@ -0,0 +1,16 @@
+// Python Lab 3 Version 2
+
+let numArr = []
+
+while (true) {
+ let userInput = prompt("Enter number or 'done' to quit: ")
+ if (userInput == 'done') {
+ alert(`The average is: ${average}`)
+ break
+ }
+ else {
+ userInput = parseInt(userInput)
+ numArr.push(userInput)
+ let numRedArr = numArr.reduce((x, y) => x + y)
+ average = numRedArr/numArr.length
+ }}
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab05/todos/css/delete-button.png b/code/josh/javascript/josh_js_lab05/todos/css/delete-button.png
new file mode 100644
index 00000000..ff061233
Binary files /dev/null and b/code/josh/javascript/josh_js_lab05/todos/css/delete-button.png differ
diff --git a/code/josh/javascript/josh_js_lab05/todos/css/site.css b/code/josh/javascript/josh_js_lab05/todos/css/site.css
new file mode 100644
index 00000000..c302ebaa
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab05/todos/css/site.css
@@ -0,0 +1,54 @@
+body {
+ background-color: rgb(204, 162, 55);
+}
+
+div {
+ display: flex;
+ flex-direction: column;
+
+}
+.completedItem {
+ text-decoration: line-through;
+}
+
+img {
+ max-width: 1vw;
+ max-height: 1vw;
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#checkbox {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table, td, th {
+ border: 1px solid;
+ border-collapse: collapse;
+ justify-items: center;
+ align-items: center;
+ align-content: center;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+p {
+ text-align: center;
+ margin: 1vw;
+}
+
+h1 {
+ text-align: center;
+}
+
+#input {
+ text-align: center;
+ margin: auto;
+}
+
+button {
+ margin: auto;
+}
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab05/todos/index.html b/code/josh/javascript/josh_js_lab05/todos/index.html
new file mode 100644
index 00000000..06887907
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab05/todos/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+ My Todo List
+
+
+
+
+
+ To Do List
+
+
+
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab05/todos/js/site.js b/code/josh/javascript/josh_js_lab05/todos/js/site.js
new file mode 100644
index 00000000..1f00bae3
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab05/todos/js/site.js
@@ -0,0 +1,31 @@
+new Vue({
+ el: '#app',
+ data: {
+ listItems: [],
+ delete: '',
+ userItem: ''
+ },
+ methods: {
+ // Appends user input to 'listItems' array and clears input field
+ addItem () {
+ this.listItems.push({
+ name: this.userItem,
+ completed: false,
+ }),
+ this.userItem = ''
+ },
+ // Item text is lined-through if complete
+ itemComplete (todoItem) {
+ return {
+ completedItem: todoItem.completed
+ }},
+ // Item is marked complete/incomplete
+ boxChecked (todoItem) {
+ let todoIndex = this.listItems.indexOf(todoItem)
+ this.listItems[todoIndex].completed = !this.listItems[todoIndex].completed
+ },
+ // Item is deleted from list
+ deleteItem (todoItem) {
+ this.listItems.splice(todoItem, 1)
+ }
+ }})
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab06/quotes/css/styles.css b/code/josh/javascript/josh_js_lab06/quotes/css/styles.css
new file mode 100644
index 00000000..375df8c4
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab06/quotes/css/styles.css
@@ -0,0 +1,10 @@
+body, html {
+ background-color: indianred;
+}
+
+#app, h1, h3 {
+ display: grid;
+ margin: auto;
+ max-width: 67vw;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab06/quotes/index.html b/code/josh/javascript/josh_js_lab06/quotes/index.html
new file mode 100644
index 00000000..c97e7db0
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab06/quotes/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ JS Lab 06
+
+
+
+
+
+
+ The Quotes App
+
+
Quote of the Day:
+ "{{ qotd.body }}"
+ - {{ qotd.author }}
+
+
+
+
+ "{{ item.body }}"
+ - {{ item.author }}
+
+
+
+
+
\ No newline at end of file
diff --git a/code/josh/javascript/josh_js_lab06/quotes/js/app.js b/code/josh/javascript/josh_js_lab06/quotes/js/app.js
new file mode 100644
index 00000000..513231ed
--- /dev/null
+++ b/code/josh/javascript/josh_js_lab06/quotes/js/app.js
@@ -0,0 +1,64 @@
+Vue.component('save-quote', {
+ data: function () {
+ return {
+ savedQuotes: []
+ }
+ },
+ template: 'Saved Quotes List
{{ item }}
',
+ props: ['favQuotes'],
+ methods: {
+ saveNewQuote() {
+ let userSearch = document.getElementById('search').value
+ this.savedQuotes.push(this.favQuotes);
+ console.log(this.savedQuotes)
+ if (this.savedQuotes.length >= 1) {
+ for (el of this.savedQuotes) {
+ console.log(el)
+ if (userSearch === el) {
+ alert('You have already saved this quote.');
+ break;
+ } else {
+ this.savedQuotes.push(this.favQuotes);
+ break;
+ }
+ }
+ } else {
+ this.savedQuotes.push(this.favQuotes);
+ };
+ },
+ },
+})
+
+new Vue ({
+ el: '#app',
+ data: {
+ output: {},
+ userInput: '',
+ typeChoice: '',
+ qotd: '',
+ },
+ mounted() {
+ this.getQOTD()
+ },
+ methods: {
+ getQuote() {
+ console.log('GET request');
+ axios.get('https://favqs.com/api/quotes/', {
+ headers: {
+ 'Authorization': 'Token token="855df50978dc9afd6bf86579913c9f8b"'},
+ params: {
+ 'filter': this.userInput,
+ 'type': this.typeChoice,
+ }
+ }).then(response => this.output = response.data.quotes)
+ .then(data => console.log(data))
+ .catch(error => console.error(error))
+ },
+ getQOTD() {
+ console.log('GET request');
+ axios.get('https://favqs.com/api/qotd/')
+ .then(response => this.qotd = response.data.quote)
+ .then(data => console.log(data))
+ .catch(error => console.error(error))
+ }
+}})
\ No newline at end of file