diff --git a/tango_with_django_project/manage.py b/tango_with_django_project/manage.py new file mode 100755 index 0000000..8af698f --- /dev/null +++ b/tango_with_django_project/manage.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == '__main__': + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tango_with_django_project.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) diff --git a/tango_with_django_project/media/.keep b/tango_with_django_project/media/.keep new file mode 100644 index 0000000..1c25d00 --- /dev/null +++ b/tango_with_django_project/media/.keep @@ -0,0 +1 @@ +A blank file for ensuring that the media/ directory is included in the media commit. \ No newline at end of file diff --git a/tango_with_django_project/media/cat.jpg b/tango_with_django_project/media/cat.jpg new file mode 100644 index 0000000..6d7f751 Binary files /dev/null and b/tango_with_django_project/media/cat.jpg differ diff --git a/tango_with_django_project/populate_rango.py b/tango_with_django_project/populate_rango.py new file mode 100644 index 0000000..a14968c --- /dev/null +++ b/tango_with_django_project/populate_rango.py @@ -0,0 +1,71 @@ +import os +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tango_with_django_project.settings') + +import django +django.setup() +from rango.models import Category, Page + +# For an explanation of what is going on here, please refer to the TwD book. + +def populate(): + python_pages = [ + {'title': 'Official Python Tutorial', + 'url':'http://docs.python.org/3/tutorial/', + 'views': 114,}, + {'title':'How to Think like a Computer Scientist', + 'url':'http://www.greenteapress.com/thinkpython/', + 'views': 53}, + {'title':'Learn Python in 10 Minutes', + 'url':'http://www.korokithakis.net/tutorials/python/', + 'views': 20} ] + + django_pages = [ + {'title':'Official Django Tutorial', + 'url':'https://docs.djangoproject.com/en/2.1/intro/tutorial01/', + 'views': 32}, + {'title':'Django Rocks', + 'url':'http://www.djangorocks.com/', + 'views': 12}, + {'title':'How to Tango with Django', + 'url':'http://www.tangowithdjango.com/', + 'views': 1258} ] + + other_pages = [ + {'title':'Bottle', + 'url':'http://bottlepy.org/docs/dev/', + 'views': 54}, + {'title':'Flask', + 'url':'http://flask.pocoo.org', + 'views': 64} ] + + cats = {'Python': {'pages': python_pages, 'views': 128, 'likes': 64}, + 'Django': {'pages': django_pages, 'views': 64, 'likes': 32}, + 'Other Frameworks': {'pages': other_pages, 'views': 32, 'likes': 16} } + + for cat, cat_data in cats.items(): + c = add_cat(cat, views=cat_data['views'], likes=cat_data['likes']) + for p in cat_data['pages']: + add_page(c, p['title'], p['url'], views=p['views']) + + for c in Category.objects.all(): + for p in Page.objects.filter(category=c): + print(f'- {c}: {p}') + +def add_page(cat, title, url, views=0): + p = Page.objects.get_or_create(category=cat, title=title)[0] + p.url=url + p.views=views + p.save() + return p + +def add_cat(name, views=0, likes=0): + c = Category.objects.get_or_create(name=name)[0] + c.views = views + c.likes = likes + c.save() + return c + +# Start execution here! +if __name__ == '__main__': + print('Starting Rango population script...') + populate() \ No newline at end of file diff --git a/tango_with_django_project/rango/__init__.py b/tango_with_django_project/rango/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tango_with_django_project/rango/admin.py b/tango_with_django_project/rango/admin.py new file mode 100644 index 0000000..57030bd --- /dev/null +++ b/tango_with_django_project/rango/admin.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from rango.models import Category, Page +from rango.models import UserProfile + +class PageAdmin(admin.ModelAdmin): + list_display = ('title', 'category', 'url') + +class CategoryAdmin(admin.ModelAdmin): + prepopulated_fields = {'slug': ('name',)} + +admin.site.register(Category, CategoryAdmin) +admin.site.register(Page, PageAdmin) +admin.site.register(UserProfile) \ No newline at end of file diff --git a/tango_with_django_project/rango/apps.py b/tango_with_django_project/rango/apps.py new file mode 100644 index 0000000..5b17213 --- /dev/null +++ b/tango_with_django_project/rango/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class RangoConfig(AppConfig): + name = 'rango' diff --git a/tango_with_django_project/rango/forms.py b/tango_with_django_project/rango/forms.py new file mode 100644 index 0000000..d48d896 --- /dev/null +++ b/tango_with_django_project/rango/forms.py @@ -0,0 +1,46 @@ +from django import forms +from django.contrib.auth.models import User +from rango.models import Page, Category, UserProfile + +# We could add these forms to views.py, but it makes sense to split them off into their own file. + +class CategoryForm(forms.ModelForm): + name = forms.CharField(max_length=Category.NAME_MAX_LENGTH, help_text="Please enter the category name.") + views = forms.IntegerField(widget=forms.HiddenInput(), initial=0) + likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0) + slug = forms.CharField(widget=forms.HiddenInput(), required=False) + + class Meta: + model = Category + fields = ('name',) + +class PageForm(forms.ModelForm): + title = forms.CharField(max_length=Page.TITLE_MAX_LENGTH, help_text="Please enter the title of the page.") + url = forms.URLField(max_length=200, help_text="Please enter the URL of the page.") + views = forms.IntegerField(widget=forms.HiddenInput(), initial=0) + + class Meta: + model = Page + exclude = ('category',) + + def clean(self): + cleaned_data = self.cleaned_data + url = cleaned_data.get('url') + + if url and not url.startswith('http://'): + url = f'http://{url}' + cleaned_data['url'] = url + + return cleaned_data + +class UserForm(forms.ModelForm): + password = forms.CharField(widget=forms.PasswordInput()) + + class Meta: + model = User + fields = ('username', 'email', 'password',) + +class UserProfileForm(forms.ModelForm): + class Meta: + model = UserProfile + fields = ('website', 'picture',) \ No newline at end of file diff --git a/tango_with_django_project/rango/models.py b/tango_with_django_project/rango/models.py new file mode 100644 index 0000000..38defb2 --- /dev/null +++ b/tango_with_django_project/rango/models.py @@ -0,0 +1,41 @@ +from django.db import models +from django.template.defaultfilters import slugify +from django.contrib.auth.models import User + +class Category(models.Model): + NAME_MAX_LENGTH = 128 + + name = models.CharField(max_length=NAME_MAX_LENGTH, unique=True) + views = models.IntegerField(default=0) + likes = models.IntegerField(default=0) + slug = models.SlugField(unique=True) + + def save(self, *args, **kwargs): + self.slug = slugify(self.name) + super(Category, self).save(*args, **kwargs) + + class Meta: + verbose_name_plural = 'Categories' + + def __str__(self): + return self.name + +class Page(models.Model): + TITLE_MAX_LENGTH = 128 + URL_MAX_LENGTH = 200 + + category = models.ForeignKey(Category, on_delete=models.CASCADE) + title = models.CharField(max_length=TITLE_MAX_LENGTH) + url = models.URLField() + views = models.IntegerField(default=0) + + def __str__(self): + return self.title + +class UserProfile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + website = models.URLField(blank=True) + picture = models.ImageField(upload_to='profile_images', blank=True) + + def __str__(self): + return self.user.username \ No newline at end of file diff --git a/tango_with_django_project/rango/templatetags/__init__.py b/tango_with_django_project/rango/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tango_with_django_project/rango/templatetags/rango_template_tags.py b/tango_with_django_project/rango/templatetags/rango_template_tags.py new file mode 100644 index 0000000..42d663d --- /dev/null +++ b/tango_with_django_project/rango/templatetags/rango_template_tags.py @@ -0,0 +1,9 @@ +from django import template +from rango.models import Category + +register = template.Library() + +@register.inclusion_tag('rango/categories.html') +def get_category_list(current_category=None): + return {'categories': Category.objects.all(), + 'current_category': current_category} \ No newline at end of file diff --git a/tango_with_django_project/rango/tests.py b/tango_with_django_project/rango/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/tango_with_django_project/rango/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/tango_with_django_project/rango/urls.py b/tango_with_django_project/rango/urls.py new file mode 100644 index 0000000..752e512 --- /dev/null +++ b/tango_with_django_project/rango/urls.py @@ -0,0 +1,16 @@ +from django.urls import path +from rango import views + +app_name = 'rango' + +urlpatterns = [ + path('', views.index, name='index'), + path('about/', views.about, name='about'), + path('category//', views.show_category, name='show_category'), + path('add_category/', views.add_category, name='add_category'), + path('category//add_page/', views.add_page, name='add_page'), + path('register/', views.register, name='register'), + path('login/', views.user_login, name='login'), + path('restricted/', views.restricted, name='restricted'), + path('logout/', views.user_logout, name='logout'), +] \ No newline at end of file diff --git a/tango_with_django_project/rango/views.py b/tango_with_django_project/rango/views.py new file mode 100644 index 0000000..81c05ed --- /dev/null +++ b/tango_with_django_project/rango/views.py @@ -0,0 +1,139 @@ +from django.shortcuts import render, redirect +from django.http import HttpResponse +from django.urls import reverse +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.decorators import login_required +from rango.models import Category, Page +from rango.forms import CategoryForm, PageForm, UserForm, UserProfileForm + +def index(request): + category_list = Category.objects.order_by('-likes')[:5] + page_list = Page.objects.order_by('-views')[:5] + + context_dict = {} + context_dict['boldmessage'] = 'Crunchy, creamy, cookie, candy, cupcake!' + context_dict['categories'] = category_list + context_dict['pages'] = page_list + context_dict['extra'] = 'From the model solution on GitHub' + + return render(request, 'rango/index.html', context=context_dict) + +def about(request): + # Spoiler: you don't need to pass a context dictionary here. + return render(request, 'rango/about.html') + +def show_category(request, category_name_slug): + context_dict = {} + + try: + category = Category.objects.get(slug=category_name_slug) + pages = Page.objects.filter(category=category) + + context_dict['pages'] = pages + context_dict['category'] = category + except Category.DoesNotExist: + context_dict['pages'] = None + context_dict['category'] = None + + return render(request, 'rango/category.html', context=context_dict) + +@login_required +def add_category(request): + form = CategoryForm() + + if request.method == 'POST': + form = CategoryForm(request.POST) + + if form.is_valid(): + form.save(commit=True) + return redirect(reverse('rango:index')) + else: + print(form.errors) + + return render(request, 'rango/add_category.html', {'form': form}) + +@login_required +def add_page(request, category_name_slug): + try: + category = Category.objects.get(slug=category_name_slug) + except: + category = None + + # You cannot add a page to a Category that does not exist... DM + if category is None: + return redirect(reverse('rango:index')) + + form = PageForm() + + if request.method == 'POST': + form = PageForm(request.POST) + + if form.is_valid(): + if category: + page = form.save(commit=False) + page.category = category + page.views = 0 + page.save() + + return redirect(reverse('rango:show_category', kwargs={'category_name_slug': category_name_slug})) + else: + print(form.errors) # This could be better done; for the purposes of TwD, this is fine. DM. + + context_dict = {'form': form, 'category': category} + return render(request, 'rango/add_page.html', context=context_dict) + +def register(request): + registered = False + + if request.method == 'POST': + user_form = UserForm(request.POST) + profile_form = UserProfileForm(request.POST) + + if user_form.is_valid() and profile_form.is_valid(): + user = user_form.save() + user.set_password(user.password) + user.save() + + profile = profile_form.save(commit=False) + profile.user = user + + if 'picture' in request.FILES: + profile.picture = request.FILES['picture'] + + profile.save() + registered = True + else: + print(user_form.errors, profile_form.errors) + else: + user_form = UserForm() + profile_form = UserProfileForm() + + return render(request, 'rango/register.html', context={'user_form': user_form, 'profile_form': profile_form, 'registered': registered}) + +def user_login(request): + if request.method == 'POST': + username = request.POST.get('username') + password = request.POST.get('password') + + user = authenticate(username=username, password=password) + + if user: + if user.is_active: + login(request, user) + return redirect(reverse('rango:index')) + else: + return HttpResponse("Your Rango account is disabled.") + else: + print(f"Invalid login details: {username}, {password}") + return HttpResponse("Invalid login details supplied.") + else: + return render(request, 'rango/login.html') + +@login_required +def restricted(request): + return render(request, 'rango/restricted.html') + +@login_required +def user_logout(request): + logout(request) + return redirect(reverse('rango:index')) \ No newline at end of file diff --git a/tango_with_django_project/static/images/rango.jpg b/tango_with_django_project/static/images/rango.jpg new file mode 100644 index 0000000..5835b53 Binary files /dev/null and b/tango_with_django_project/static/images/rango.jpg differ diff --git a/tango_with_django_project/tango_with_django_project/__init__.py b/tango_with_django_project/tango_with_django_project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tango_with_django_project/tango_with_django_project/settings.py b/tango_with_django_project/tango_with_django_project/settings.py new file mode 100644 index 0000000..ba7dc26 --- /dev/null +++ b/tango_with_django_project/tango_with_django_project/settings.py @@ -0,0 +1,129 @@ +""" +Django settings for tango_with_django_project project. + +Generated by 'django-admin startproject' using Django 2.1.5. + +For more information on this file, see +https://docs.djangoproject.com/en/2.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.1/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates') +STATIC_DIR = os.path.join(BASE_DIR, 'static') +MEDIA_DIR = os.path.join(BASE_DIR, 'media') + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'sq_z*m=yr)aiu$9lyzf@)&-!o(yjs=)9igwhuco$d7@a3jed=@' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + +LOGIN_URL = 'rango:login' + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rango', +] + +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 = 'tango_with_django_project.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [TEMPLATE_DIR, ], + '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', + 'django.template.context_processors.media', + ], + }, + }, +] + +WSGI_APPLICATION = 'tango_with_django_project.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.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/2.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.1/howto/static-files/ + +STATIC_URL = '/static/' +STATICFILES_DIRS = [STATIC_DIR, ] + +MEDIA_ROOT = MEDIA_DIR +MEDIA_URL = '/media/' \ No newline at end of file diff --git a/tango_with_django_project/tango_with_django_project/urls.py b/tango_with_django_project/tango_with_django_project/urls.py new file mode 100644 index 0000000..c3eb2ba --- /dev/null +++ b/tango_with_django_project/tango_with_django_project/urls.py @@ -0,0 +1,28 @@ +"""tango_with_django_project URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.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 path +from django.urls import include +from rango import views +from django.conf import settings +from django.conf.urls.static import static + +urlpatterns = [ + path('', views.index, name='index'), + path('rango/', include('rango.urls')), + # 3 - The above maps any URLs starting with rango/ to be handled by rango. + path('admin/', admin.site.urls), +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/tango_with_django_project/tango_with_django_project/wsgi.py b/tango_with_django_project/tango_with_django_project/wsgi.py new file mode 100644 index 0000000..d3a1b1b --- /dev/null +++ b/tango_with_django_project/tango_with_django_project/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for tango_with_django_project 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/2.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tango_with_django_project.settings') + +application = get_wsgi_application() diff --git a/tango_with_django_project/templates/rango/.hidden b/tango_with_django_project/templates/rango/.hidden new file mode 100644 index 0000000..f934a67 --- /dev/null +++ b/tango_with_django_project/templates/rango/.hidden @@ -0,0 +1 @@ +This is a hidden file. If you're a student doing this course for credit, cloning this repository won't get you very far. There's subtle things placed here and there that can prove to an astute professor that you just did that. Better to go and read through the book by yourself. \ No newline at end of file diff --git a/tango_with_django_project/templates/rango/about.html b/tango_with_django_project/templates/rango/about.html new file mode 100644 index 0000000..ac376a5 --- /dev/null +++ b/tango_with_django_project/templates/rango/about.html @@ -0,0 +1,16 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + About Rango +{% endblock %} + +{% block body_block %} +

Rango says...

+
+ here is the about page.
+ This tutorial has been put together by David Maxwell.
+
+Picture of Rango +Picture of a Cat +{% endblock %} diff --git a/tango_with_django_project/templates/rango/add_category.html b/tango_with_django_project/templates/rango/add_category.html new file mode 100644 index 0000000..d0c9a50 --- /dev/null +++ b/tango_with_django_project/templates/rango/add_category.html @@ -0,0 +1,24 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + Add a Category +{% endblock %} + +{% block body_block %} +

Add a Category

+
+
+ {% csrf_token %} + {% for hidden in form.hidden_fields %} + {{ hidden }} + {% endfor %} + {% for field in form.visible_fields %} + {{ field.errors }} + {{ field.help_text }} + {{ field }} + {% endfor %} + +
+
+{% endblock %} diff --git a/tango_with_django_project/templates/rango/add_page.html b/tango_with_django_project/templates/rango/add_page.html new file mode 100644 index 0000000..4e860c7 --- /dev/null +++ b/tango_with_django_project/templates/rango/add_page.html @@ -0,0 +1,25 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + Add a Page +{% endblock %} + +{% block body_block %} +

Add a Page to {{ category.name }}

+
+
+ {% csrf_token %} + {% csrf_token %} + {% for hidden in form.hidden_fields %} + {{ hidden }} + {% endfor %} + {% for field in form.visible_fields %} + {{ field.errors }} + {{ field.help_text }} + {{ field }} + {% endfor %} + +
+
+{% endblock %} diff --git a/tango_with_django_project/templates/rango/base.html b/tango_with_django_project/templates/rango/base.html new file mode 100644 index 0000000..34969cd --- /dev/null +++ b/tango_with_django_project/templates/rango/base.html @@ -0,0 +1,41 @@ + +{% load static %} +{% load rango_template_tags %} + + + + + + Rango - + {% block title_block %} + How to Tango with Django! + {% endblock %} + + + +
+ {% block body_block %} + {% endblock %} +
+
+ {% block sidebar_block %} + {% get_category_list category %} + {% endblock %} +
+
+
+ +
+ + diff --git a/tango_with_django_project/templates/rango/categories.html b/tango_with_django_project/templates/rango/categories.html new file mode 100644 index 0000000..c095bd0 --- /dev/null +++ b/tango_with_django_project/templates/rango/categories.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/tango_with_django_project/templates/rango/category.html b/tango_with_django_project/templates/rango/category.html new file mode 100644 index 0000000..88ff918 --- /dev/null +++ b/tango_with_django_project/templates/rango/category.html @@ -0,0 +1,31 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + {% if category %} + {{ category.name }} + {% else %} + Unknown Category + {% endif %} +{% endblock %} + +{% block body_block %} + {% if category %} +

{{ category.name }}

+ {% if pages %} + + {% else %} + No pages currently in category. + {% endif %} + + {% if user.is_authenticated %} + Add Page
+ {% endif %} + {% else %} + The specified category does not exist. + {% endif %} +{% endblock %} diff --git a/tango_with_django_project/templates/rango/index.html b/tango_with_django_project/templates/rango/index.html new file mode 100644 index 0000000..4c45f8d --- /dev/null +++ b/tango_with_django_project/templates/rango/index.html @@ -0,0 +1,47 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + Homepage +{% endblock %} + +{% block body_block %} +

Rango says...

+
+ {% if user.is_authenticated %} + howdy {{ user.username }}! + {% else %} + hey there partner! + {% endif %} +
+ {{ boldmessage }}
+
+ +
+

Most Liked Categories

+{% if categories %} + +{% else %} + There are no categories present. +{% endif %} +
+ +
+

Most Viewed Pages

+{% if pages %} + +{% else %} + There are no pages present. +{% endif %} +
+ +Picture of Rango +{% endblock %} diff --git a/tango_with_django_project/templates/rango/login.html b/tango_with_django_project/templates/rango/login.html new file mode 100644 index 0000000..10210e8 --- /dev/null +++ b/tango_with_django_project/templates/rango/login.html @@ -0,0 +1,18 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + Login +{% endblock %} + +{% block body_block %} +

Login to Rango

+
+ {% csrf_token %} + Username: +
+ Password: +
+ +
+{% endblock %} diff --git a/tango_with_django_project/templates/rango/register.html b/tango_with_django_project/templates/rango/register.html new file mode 100644 index 0000000..9efda62 --- /dev/null +++ b/tango_with_django_project/templates/rango/register.html @@ -0,0 +1,23 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + Register +{% endblock %} + +{% block body_block %} +

Register for Rango

+{% if registered %} +Rango says: thank you for registering! +Return to the homepage.
+{% else %} +Rango says: register here!
+
+ {% csrf_token %} + {{ user_form.as_p }} + {{ profile_form.as_p }} + + +
+{% endif %} +{% endblock %} diff --git a/tango_with_django_project/templates/rango/restricted.html b/tango_with_django_project/templates/rango/restricted.html new file mode 100644 index 0000000..b36b953 --- /dev/null +++ b/tango_with_django_project/templates/rango/restricted.html @@ -0,0 +1,12 @@ +{% extends 'rango/base.html' %} +{% load static %} + +{% block title_block %} + Restricted Page +{% endblock %} + +{% block body_block %} +

Restricted Page

+Since you're logged in, you can see this text!
+David was here! +{% endblock %}