From e98d92fb0b4f604c9998cd9e94d6c924741d43c9 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Mon, 16 Jan 2017 16:53:44 -0800 Subject: [PATCH 01/74] added site --- imagersite/imagersite/__init__.py | 0 imagersite/imagersite/settings.py | 120 ++++++++++++++++++++++++++++++ imagersite/imagersite/urls.py | 21 ++++++ imagersite/imagersite/wsgi.py | 16 ++++ imagersite/manage.py | 22 ++++++ 5 files changed, 179 insertions(+) create mode 100644 imagersite/imagersite/__init__.py create mode 100644 imagersite/imagersite/settings.py create mode 100644 imagersite/imagersite/urls.py create mode 100644 imagersite/imagersite/wsgi.py create mode 100755 imagersite/manage.py diff --git a/imagersite/imagersite/__init__.py b/imagersite/imagersite/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py new file mode 100644 index 0000000..c1f24be --- /dev/null +++ b/imagersite/imagersite/settings.py @@ -0,0 +1,120 @@ +""" +Django settings for imagersite project. + +Generated by 'django-admin startproject' using Django 1.10.5. + +For more information on this file, see +https://docs.djangoproject.com/en/1.10/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.10/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__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '5m(o9rkvq-2$u452_313+-m9&gn*8%mqj+&^yum=r!%h%@(%!j' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + '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 = 'imagersite.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 = 'imagersite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.10/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/1.10/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/1.10/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/1.10/howto/static-files/ + +STATIC_URL = '/static/' diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py new file mode 100644 index 0000000..384e743 --- /dev/null +++ b/imagersite/imagersite/urls.py @@ -0,0 +1,21 @@ +"""imagersite URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.10/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.conf.urls import url, include + 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) +""" +from django.conf.urls import url +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', admin.site.urls), +] diff --git a/imagersite/imagersite/wsgi.py b/imagersite/imagersite/wsgi.py new file mode 100644 index 0000000..8ef8781 --- /dev/null +++ b/imagersite/imagersite/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for imagersite 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/1.10/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "imagersite.settings") + +application = get_wsgi_application() diff --git a/imagersite/manage.py b/imagersite/manage.py new file mode 100755 index 0000000..b28a0f2 --- /dev/null +++ b/imagersite/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "imagersite.settings") + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + 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?" + ) + raise + execute_from_command_line(sys.argv) From 1bb7e551154eea9b34a4fe7917defaa2efd4dbc1 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Mon, 16 Jan 2017 18:00:23 -0800 Subject: [PATCH 02/74] user profile fields built --- imagersite/imager_profile/__init__.py | 0 imagersite/imager_profile/admin.py | 3 ++ imagersite/imager_profile/apps.py | 5 ++++ .../imager_profile/migrations/__init__.py | 0 imagersite/imager_profile/models.py | 28 +++++++++++++++++++ imagersite/imager_profile/tests.py | 3 ++ imagersite/imager_profile/views.py | 3 ++ imagersite/imagersite/settings.py | 11 ++++++-- 8 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 imagersite/imager_profile/__init__.py create mode 100644 imagersite/imager_profile/admin.py create mode 100644 imagersite/imager_profile/apps.py create mode 100644 imagersite/imager_profile/migrations/__init__.py create mode 100644 imagersite/imager_profile/models.py create mode 100644 imagersite/imager_profile/tests.py create mode 100644 imagersite/imager_profile/views.py diff --git a/imagersite/imager_profile/__init__.py b/imagersite/imager_profile/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/imagersite/imager_profile/admin.py b/imagersite/imager_profile/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/imagersite/imager_profile/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/imagersite/imager_profile/apps.py b/imagersite/imager_profile/apps.py new file mode 100644 index 0000000..8900e6d --- /dev/null +++ b/imagersite/imager_profile/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ImagerProfileConfig(AppConfig): + name = 'imager_profile' diff --git a/imagersite/imager_profile/migrations/__init__.py b/imagersite/imager_profile/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py new file mode 100644 index 0000000..c623f98 --- /dev/null +++ b/imagersite/imager_profile/models.py @@ -0,0 +1,28 @@ +from django.db import models +from django.contrib.auth.models import User +import uuid + +from django.db.models.signals import post_save +from django.dispatch import receiver + +# Create your models here. + + +class UserProfile(models.Model): + """The imager user and all their attributes.""" + + user = models.OneToOneField( + User, + related_name="profile", + on_delete=models.CASCADE + ) + CAMERA_CHOICES = ('Nikon', 'iPhone', 'Canon'), + ACTIVE = False + camera_type = models.CharField(max_length=10, choices=CAMERA_CHOICES, null=True, blank=True), + address = models.CharField(max_length=40, null=True, blank=True), + bio = models.TextField(), + personal_website = models.URLField(), + for_hire = models.BooleanField(default=False), + travel_distance = models.IntegerField(null=True, blank=True) + phone_number = models.CharField(max_length=15, null=True, blank=True) + photography_type = models.CharField(max_length=20, null=True, blank=True) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/imagersite/imager_profile/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/imagersite/imager_profile/views.py b/imagersite/imager_profile/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/imagersite/imager_profile/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index c1f24be..70a2211 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -75,8 +75,15 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': os.environ['IMAGER_DATABASE'], + # 'USER': os.environ['DATABASE_USER'], + # 'PASSWORD': os.environ['DATABASE_PASSWORD'], + # 'HOST': '127.0.0.1', + # 'PORT': '5432', + 'TEST': { + 'NAME': os.environ['TEST_IMAGER'] + } } } From bc7867f262f94a927c4cad297ae0e769c04a630f Mon Sep 17 00:00:00 2001 From: pasaunders Date: Mon, 16 Jan 2017 18:17:35 -0800 Subject: [PATCH 03/74] pre-manager statusquo --- .gitignore | 1 + imagersite/imager_profile/models.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8312747..d6499d1 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ bin/ lib64 pyvenv.cfg share/ +pip-selfcheck.json # PyInstaller # Usually these files are written by a python script from a template diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index c623f98..48eba4d 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -8,7 +8,7 @@ # Create your models here. -class UserProfile(models.Model): +class ImagerProfile(models.Model): """The imager user and all their attributes.""" user = models.OneToOneField( From 50cd84c5fdf0603aba464c88421db706970cb7be Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Mon, 16 Jan 2017 19:18:57 -0800 Subject: [PATCH 04/74] add make profile when user is made and tests --- .../imager_profile/migrations/0001_initial.py | 29 ++++++++++++ imagersite/imager_profile/models.py | 8 +++- imagersite/imager_profile/tests.py | 47 +++++++++++++++++++ imagersite/imagersite/settings.py | 1 + 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 imagersite/imager_profile/migrations/0001_initial.py diff --git a/imagersite/imager_profile/migrations/0001_initial.py b/imagersite/imager_profile/migrations/0001_initial.py new file mode 100644 index 0000000..93870a7 --- /dev/null +++ b/imagersite/imager_profile/migrations/0001_initial.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-17 03:06 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ImagerProfile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('travel_distance', models.IntegerField(blank=True, null=True)), + ('phone_number', models.CharField(blank=True, max_length=15, null=True)), + ('photography_type', models.CharField(blank=True, max_length=20, null=True)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index 48eba4d..eeb4bba 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -1,6 +1,5 @@ from django.db import models from django.contrib.auth.models import User -import uuid from django.db.models.signals import post_save from django.dispatch import receiver @@ -26,3 +25,10 @@ class ImagerProfile(models.Model): travel_distance = models.IntegerField(null=True, blank=True) phone_number = models.CharField(max_length=15, null=True, blank=True) photography_type = models.CharField(max_length=20, null=True, blank=True) + + +@receiver(post_save, sender=User) +def make_profile_for_user(sender, instance, **kwargs): + """Called when user is made and hooks that user to a profile.""" + new_profile = ImagerProfile(user=instance) + new_profile.save() diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index 7ce503c..f1de2f6 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -1,3 +1,50 @@ +"""Tests for the imager_profile app.""" from django.test import TestCase +from django.contrib.auth.models import User +from imager_profile.models import ImagerProfile +import factory # Create your tests here. + + +class ProfileTestCase(TestCase): + """The Profile Model test runner.""" + + class UserFactory(factory.django.DjangoModelFactory): + """Makes users.""" + + class Meta: + """Meta.""" + + model = User + + username = factory.Sequence(lambda n: "The Chosen {}".format(n)) + email = factory.LazyAttribute( + lambda x: "{}@foo.com".format(x.username.replace(" ", "")) + ) + + def setUp(self): + """The appropriate setup for the appropriate test.""" + self.foo = "bar" + self.users = [self.UserFactory.create() for i in range(20)] + + def thing_and_stuff(self): + self.thing = "stuff" + + def test_profile_is_made_when_user_is_saved(self): + """.""" + self.thing_and_stuff() + self.assertTrue(ImagerProfile.objects.count() == 20) + self.assertTrue(self.thing == "stuff") + + def test_profile_is_associated_with_actual_users(self): + """.""" + profile = ImagerProfile.objects.first() + self.assertTrue(hasattr(profile, "user")) + self.assertIsInstance(profile.user, User) + + def test_user_has_profile_attached(self): + """.""" + user = self.users[0] + self.assertTrue(hasattr(user, "profile")) + self.assertIsInstance(user.profile, ImagerProfile) diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index 70a2211..cdf4ced 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -37,6 +37,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'imager_profile' ] MIDDLEWARE = [ From 3aa40d18c1871871c825a2a30b837f4bbf878ca7 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Mon, 16 Jan 2017 19:39:01 -0800 Subject: [PATCH 05/74] add is_active and ActiveProfileManager --- imagersite/imager_profile/models.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index eeb4bba..cfc3350 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -1,22 +1,34 @@ from django.db import models from django.contrib.auth.models import User - +from django.utils.encoding import python_2_unicode_compatible from django.db.models.signals import post_save from django.dispatch import receiver # Create your models here. +class ActiveProfileManager(models.Manager): + """Create Model Manager for Active Profiles.""" + + def get_queryset(self): + """Return active users.""" + qs = super(ActiveProfileManager, self).get_queryset() + return qs.filter(user__is_active__exact=True) + + +@python_2_unicode_compatible class ImagerProfile(models.Model): """The imager user and all their attributes.""" + objects = models.Manager() + active = ActiveProfileManager() + user = models.OneToOneField( User, related_name="profile", on_delete=models.CASCADE ) CAMERA_CHOICES = ('Nikon', 'iPhone', 'Canon'), - ACTIVE = False camera_type = models.CharField(max_length=10, choices=CAMERA_CHOICES, null=True, blank=True), address = models.CharField(max_length=40, null=True, blank=True), bio = models.TextField(), @@ -26,6 +38,11 @@ class ImagerProfile(models.Model): phone_number = models.CharField(max_length=15, null=True, blank=True) photography_type = models.CharField(max_length=20, null=True, blank=True) + @property + def is_active(self): + """Return True if user associated with this profile is active.""" + return self._is_active + @receiver(post_save, sender=User) def make_profile_for_user(sender, instance, **kwargs): From ccb4011867334749562b081ef804a8a1b9976e77 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Mon, 16 Jan 2017 23:11:33 -0800 Subject: [PATCH 06/74] added __str__ method and default app config --- imagersite/imager_profile/__init__.py | 1 + imagersite/imager_profile/models.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/imagersite/imager_profile/__init__.py b/imagersite/imager_profile/__init__.py index e69de29..4a991a4 100644 --- a/imagersite/imager_profile/__init__.py +++ b/imagersite/imager_profile/__init__.py @@ -0,0 +1 @@ +default_app_config = 'imager_profile.apps.ImagerProfileConfig' diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index cfc3350..ec2e88e 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -1,3 +1,5 @@ +"""Models for imager_profile.""" + from django.db import models from django.contrib.auth.models import User from django.utils.encoding import python_2_unicode_compatible @@ -29,7 +31,12 @@ class ImagerProfile(models.Model): on_delete=models.CASCADE ) CAMERA_CHOICES = ('Nikon', 'iPhone', 'Canon'), - camera_type = models.CharField(max_length=10, choices=CAMERA_CHOICES, null=True, blank=True), + camera_type = models.CharField( + max_length=10, + choices=CAMERA_CHOICES, + null=True, + blank=True + ), address = models.CharField(max_length=40, null=True, blank=True), bio = models.TextField(), personal_website = models.URLField(), @@ -43,6 +50,10 @@ def is_active(self): """Return True if user associated with this profile is active.""" return self._is_active + def __str__(self): + """Display user data as a string.""" + return "User: {}, Camera: {}, Address: {}, Phone number: {} For Hire? {}, Photography style: {}".format(self.user, self.camera_type, self.address, self.phone_number, self.for_hire, self.photography_type) + @receiver(post_save, sender=User) def make_profile_for_user(sender, instance, **kwargs): From c01f3bc82851b7335cefb91bd6e8c3b90ec305e6 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 09:33:57 -0800 Subject: [PATCH 07/74] remove and fix some tests --- imagersite/imager_profile/tests.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index f1de2f6..ae18524 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -4,8 +4,6 @@ from imager_profile.models import ImagerProfile import factory -# Create your tests here. - class ProfileTestCase(TestCase): """The Profile Model test runner.""" @@ -28,23 +26,18 @@ def setUp(self): self.foo = "bar" self.users = [self.UserFactory.create() for i in range(20)] - def thing_and_stuff(self): - self.thing = "stuff" - def test_profile_is_made_when_user_is_saved(self): - """.""" - self.thing_and_stuff() + """Test profile is made when user is saved.""" self.assertTrue(ImagerProfile.objects.count() == 20) - self.assertTrue(self.thing == "stuff") def test_profile_is_associated_with_actual_users(self): - """.""" + """Test profile is associated with actual users.""" profile = ImagerProfile.objects.first() self.assertTrue(hasattr(profile, "user")) self.assertIsInstance(profile.user, User) def test_user_has_profile_attached(self): - """.""" + """Test user has profile attached.""" user = self.users[0] self.assertTrue(hasattr(user, "profile")) self.assertIsInstance(user.profile, ImagerProfile) From 44bdabfc99cbf5809aef4c8f91eb1ac51e3bec6f Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 10:09:47 -0800 Subject: [PATCH 08/74] add requirements.pip --- imagersite/requirements.pip | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 imagersite/requirements.pip diff --git a/imagersite/requirements.pip b/imagersite/requirements.pip new file mode 100644 index 0000000..74feca4 --- /dev/null +++ b/imagersite/requirements.pip @@ -0,0 +1,18 @@ +decorator==4.0.11 +Django==1.10.5 +factory-boy==2.8.1 +Faker==0.7.7 +ipython==5.1.0 +ipython-genutils==0.1.0 +pexpect==4.2.1 +pickleshare==0.7.4 +pkg-resources==0.0.0 +prompt-toolkit==1.0.9 +psycopg2==2.6.2 +ptyprocess==0.5.1 +Pygments==2.1.3 +python-dateutil==2.6.0 +simplegeneric==0.8.1 +six==1.10.0 +traitlets==4.3.1 +wcwidth==0.1.7 From 08a4a1b62850d7da89d02f7104fee49dfc8c96a3 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 10:17:04 -0800 Subject: [PATCH 09/74] add readme --- README.md | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 552d117..45227bc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,38 @@ -# django-imager -django introduction assignment +# Django-Imager +## Getting Started + +Clone this repository into whatever directory you want to work from. + +```bash +$ git clone https://github.com/pasaunders/django-imager.git +``` + +Assuming that you have access to Python 3 at the system level, start up a new virtual environment. + +```bash +$ cd django-imager +$ python3 -m venv . +$ source bin/activate +``` + +Once your environment has been activated, make sure to install Django and all of this project's required packages. + +```bash +(django-imager) $ pip install -r requirements.pip +``` + +Navigate to the project root, `imagersite`, and apply the migrations for the app. + +```bash +(django-imager) $ cd lending_library +(django-imager) $ ./manage.py migrate +``` + +Finally, run the server in order to server the app on `localhost` + +```bash +(django-imager) $ ./manage.py runserver +``` + +Django will typically serve on port 8000, unless you specify otherwise. +You can access the locally-served site at the address `http://localhost:8000`. \ No newline at end of file From 0cfedb8a1d93a8da1667612565c87a3ddc6352eb Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 10:23:02 -0800 Subject: [PATCH 10/74] change is_active --- imagersite/imager_profile/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index ec2e88e..19f8b09 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -48,7 +48,7 @@ class ImagerProfile(models.Model): @property def is_active(self): """Return True if user associated with this profile is active.""" - return self._is_active + return self.user.is_active def __str__(self): """Display user data as a string.""" From ee2b05dfd2b24881175b4e41b02553960816e330 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 10:27:42 -0800 Subject: [PATCH 11/74] fixed some stuff --- imagersite/imager_profile/models.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index 19f8b09..a9779a3 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -30,17 +30,21 @@ class ImagerProfile(models.Model): related_name="profile", on_delete=models.CASCADE ) - CAMERA_CHOICES = ('Nikon', 'iPhone', 'Canon'), + CAMERA_CHOICES = [ + ('Nikon', 'Nikon'), + ('iPhone', 'iPhone'), + ('Canon', 'Canon') + ] camera_type = models.CharField( max_length=10, choices=CAMERA_CHOICES, null=True, blank=True - ), + ) address = models.CharField(max_length=40, null=True, blank=True), - bio = models.TextField(), - personal_website = models.URLField(), - for_hire = models.BooleanField(default=False), + bio = models.TextField(default="") + personal_website = models.URLField(default="") + for_hire = models.BooleanField(default=False) travel_distance = models.IntegerField(null=True, blank=True) phone_number = models.CharField(max_length=15, null=True, blank=True) photography_type = models.CharField(max_length=20, null=True, blank=True) From 27fd374fadb9eef3cfd11dc99005a2c907be15ad Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 10:28:58 -0800 Subject: [PATCH 12/74] did makemigrations --- .../migrations/0002_auto_20170117_1828.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 imagersite/imager_profile/migrations/0002_auto_20170117_1828.py diff --git a/imagersite/imager_profile/migrations/0002_auto_20170117_1828.py b/imagersite/imager_profile/migrations/0002_auto_20170117_1828.py new file mode 100644 index 0000000..42a32ed --- /dev/null +++ b/imagersite/imager_profile/migrations/0002_auto_20170117_1828.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-17 18:28 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('imager_profile', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='imagerprofile', + name='bio', + field=models.TextField(default=''), + ), + migrations.AddField( + model_name='imagerprofile', + name='camera_type', + field=models.CharField(blank=True, choices=[('Nikon', 'Nikon'), ('iPhone', 'iPhone'), ('Canon', 'Canon')], max_length=10, null=True), + ), + migrations.AddField( + model_name='imagerprofile', + name='for_hire', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='imagerprofile', + name='personal_website', + field=models.URLField(default=''), + ), + ] From 53d177a191e94cfd46611562b23b2e0ff07def97 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 15:21:11 -0800 Subject: [PATCH 13/74] built .travis.yml and requirements.pip --- .travis.yml | 15 +++++++++++++++ requirements.pip | 15 +++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 .travis.yml create mode 100644 requirements.pip diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..07bdb11 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +decorator==4.0.11 +Django==1.10.5 +ipython==5.1.0 +ipython-genutils==0.1.0 +pexpect==4.2.1 +pickleshare==0.7.4 +pkg-resources==0.0.0 +prompt-toolkit==1.0.9 +psycopg2==2.6.2 +ptyprocess==0.5.1 +Pygments==2.1.3 +simplegeneric==0.8.1 +six==1.10.0 +traitlets==4.3.1 +wcwidth==0.1.7 diff --git a/requirements.pip b/requirements.pip new file mode 100644 index 0000000..07bdb11 --- /dev/null +++ b/requirements.pip @@ -0,0 +1,15 @@ +decorator==4.0.11 +Django==1.10.5 +ipython==5.1.0 +ipython-genutils==0.1.0 +pexpect==4.2.1 +pickleshare==0.7.4 +pkg-resources==0.0.0 +prompt-toolkit==1.0.9 +psycopg2==2.6.2 +ptyprocess==0.5.1 +Pygments==2.1.3 +simplegeneric==0.8.1 +six==1.10.0 +traitlets==4.3.1 +wcwidth==0.1.7 From 061bb4ca462d26edefa782e31c9b5a80db8d2b97 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 15:29:51 -0800 Subject: [PATCH 14/74] added readme widget --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 45227bc..784532d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Build Status](https://travis-ci.org/pasaunders/django-imager.svg?branch=master)](https://travis-ci.org/pasaunders/django-imager) # Django-Imager ## Getting Started From 071b439c2f2e8e47d343f0efdc2910f274d9c633 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:22:14 -0800 Subject: [PATCH 15/74] travis debugging --- .travis.yml | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07bdb11..cbc029a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,18 @@ -decorator==4.0.11 -Django==1.10.5 -ipython==5.1.0 -ipython-genutils==0.1.0 -pexpect==4.2.1 -pickleshare==0.7.4 -pkg-resources==0.0.0 -prompt-toolkit==1.0.9 -psycopg2==2.6.2 -ptyprocess==0.5.1 -Pygments==2.1.3 -simplegeneric==0.8.1 -six==1.10.0 -traitlets==4.3.1 -wcwidth==0.1.7 +language: python +python: + - "2.7" + - "3.5" + +# command to install dependencies +install: + - pip install . + - pip install -r requirements.txt + +services: + - postgresql + +before_script: + - psql -c 'create database travis_ci_test;' -U postgres + +# command to run tests +script: python manage.py test \ No newline at end of file From d95f9acaa9bd34a4eeffa411146a6ac8621ce25b Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:36:22 -0800 Subject: [PATCH 16/74] travis debugging --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cbc029a..0610318 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ python: # command to install dependencies install: - - pip install . + # - pip install . - pip install -r requirements.txt services: From 253909242bc76d5c6e09616b2c6f692330ca7927 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:37:45 -0800 Subject: [PATCH 17/74] travis debugging --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0610318..3911138 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ python: # command to install dependencies install: # - pip install . - - pip install -r requirements.txt + - pip install -r requirements.pip services: - postgresql From c1b08cd85ce14c82a0d86a1c71f4eeecaee1e2c4 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:39:19 -0800 Subject: [PATCH 18/74] travis debugging --- requirements.pip | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.pip b/requirements.pip index 07bdb11..54667b0 100644 --- a/requirements.pip +++ b/requirements.pip @@ -4,7 +4,6 @@ ipython==5.1.0 ipython-genutils==0.1.0 pexpect==4.2.1 pickleshare==0.7.4 -pkg-resources==0.0.0 prompt-toolkit==1.0.9 psycopg2==2.6.2 ptyprocess==0.5.1 From 580c94c2a9fde30c679a67515bd39e2aa802a0f1 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:41:12 -0800 Subject: [PATCH 19/74] travis debugging --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3911138..792b15f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ before_script: - psql -c 'create database travis_ci_test;' -U postgres # command to run tests -script: python manage.py test \ No newline at end of file +script: python imagersite.manage.py test \ No newline at end of file From e4b35464b39b96924e8f10c65825b5f2bddb6526 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:43:27 -0800 Subject: [PATCH 20/74] travis debugging --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 792b15f..ffad062 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ before_script: - psql -c 'create database travis_ci_test;' -U postgres # command to run tests -script: python imagersite.manage.py test \ No newline at end of file +script: python imagersite/manage.py test \ No newline at end of file From f9a852370f5608b12bbb5f56752e9e3d1eb0b737 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:46:11 -0800 Subject: [PATCH 21/74] travis debugging --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 784532d..12d0439 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -[![Build Status](https://travis-ci.org/pasaunders/django-imager.svg?branch=master)](https://travis-ci.org/pasaunders/django-imager) -# Django-Imager +[![Build Status](https://travis-ci.org/pasaunders/django-imager.svg?branch=master)](https://travis-ci.org/pasaunders/django-imager)# Django-Imager ## Getting Started Clone this repository into whatever directory you want to work from. From 7f5d9569acd6f4a3773d34e8f9f3e7ef40a3482f Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 16:49:43 -0800 Subject: [PATCH 22/74] travis debugging --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12d0439..5152b0d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/pasaunders/django-imager.svg?branch=master)](https://travis-ci.org/pasaunders/django-imager)# Django-Imager +[![Build Status](https://travis-ci.org/pasaunders/django-imager.svg?branch=front-end-1)](https://travis-ci.org/pasaunders/django-imager) ## Getting Started Clone this repository into whatever directory you want to work from. From 00c1b3f3708462c35c58a1cb3881316d5df792dc Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 17:16:08 -0800 Subject: [PATCH 23/74] add admin, some teplates and other stuff --- imagersite/imager_profile/admin.py | 4 ++++ imagersite/imagersite/settings.py | 3 ++- imagersite/imagersite/templates/imagersite/base.html | 9 +++++++++ imagersite/imagersite/templates/imagersite/home.html | 3 +++ imagersite/imagersite/urls.py | 2 ++ imagersite/imagersite/views.py | 9 +++++++++ 6 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 imagersite/imagersite/templates/imagersite/base.html create mode 100644 imagersite/imagersite/templates/imagersite/home.html create mode 100644 imagersite/imagersite/views.py diff --git a/imagersite/imager_profile/admin.py b/imagersite/imager_profile/admin.py index 8c38f3f..8295835 100644 --- a/imagersite/imager_profile/admin.py +++ b/imagersite/imager_profile/admin.py @@ -1,3 +1,7 @@ from django.contrib import admin +from imager_profile.models import ImagerProfile # Register your models here. + + +admin.site.register(ImagerProfile) diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index cdf4ced..d6eacd6 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -37,7 +37,8 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'imager_profile' + 'imager_profile', + 'imagersite' ] MIDDLEWARE = [ diff --git a/imagersite/imagersite/templates/imagersite/base.html b/imagersite/imagersite/templates/imagersite/base.html new file mode 100644 index 0000000..cfea42a --- /dev/null +++ b/imagersite/imagersite/templates/imagersite/base.html @@ -0,0 +1,9 @@ + + + + App + + +{% block content %}{% endblock %} + + \ No newline at end of file diff --git a/imagersite/imagersite/templates/imagersite/home.html b/imagersite/imagersite/templates/imagersite/home.html new file mode 100644 index 0000000..9c34b75 --- /dev/null +++ b/imagersite/imagersite/templates/imagersite/home.html @@ -0,0 +1,3 @@ +{% extends 'imagersite/base.html' %} + +Home Page \ No newline at end of file diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index 384e743..d1e0017 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -15,7 +15,9 @@ """ from django.conf.urls import url from django.contrib import admin +from imagersite.views import home_view urlpatterns = [ url(r'^admin/', admin.site.urls), + url(r'^$', home_view, name='homepage') ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py new file mode 100644 index 0000000..c0ce2a7 --- /dev/null +++ b/imagersite/imagersite/views.py @@ -0,0 +1,9 @@ +"""Views.""" +from django.shortcuts import render + + +def home_view(request): + """The home view.""" + return render(request, + "imagersite/home.html" + ) From 19494912c104ae9dc721e1395fc455f8e3948add Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 17:24:29 -0800 Subject: [PATCH 24/74] fix home template --- imagersite/imagersite/templates/imagersite/home.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imagersite/imagersite/templates/imagersite/home.html b/imagersite/imagersite/templates/imagersite/home.html index 9c34b75..367883c 100644 --- a/imagersite/imagersite/templates/imagersite/home.html +++ b/imagersite/imagersite/templates/imagersite/home.html @@ -1,3 +1,4 @@ {% extends 'imagersite/base.html' %} - -Home Page \ No newline at end of file +{% block content %} +

Home Page

+{% endblock content %} \ No newline at end of file From d3d1e5778d5d8a87c26e771d30fda52701444fe8 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 17 Jan 2017 18:12:11 -0800 Subject: [PATCH 25/74] change url --- imagersite/imagersite/urls.py | 13 +++++++++---- imagersite/imagersite/views.py | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index d1e0017..e5ded31 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -13,11 +13,16 @@ 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from django.conf.urls import url -from django.contrib import admin -from imagersite.views import home_view +from django.conf.urls import include, url +from django.contrib import ( + admin +) +from imagersite.views import ( + home_view +) urlpatterns = [ url(r'^admin/', admin.site.urls), - url(r'^$', home_view, name='homepage') + url(r'^$', home_view, name='homepage'), + url(r'^accounts/$', include('registration.backends.hmac.urls')), ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index c0ce2a7..d5681d0 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -1,5 +1,6 @@ """Views.""" from django.shortcuts import render +import registration.backends.hmac.views.RegistrationView def home_view(request): From 94b6e321ecc8ac538c3a52b7145610381c07e1ae Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 17 Jan 2017 18:34:50 -0800 Subject: [PATCH 26/74] some bootstrap code, one more test, requirements.pip updated --- imagersite/imager_profile/tests.py | 7 +++++++ imagersite/imagersite/settings.py | 1 + imagersite/requirements.pip | 1 - requirements.pip | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index ae18524..35186c3 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -41,3 +41,10 @@ def test_user_has_profile_attached(self): user = self.users[0] self.assertTrue(hasattr(user, "profile")) self.assertIsInstance(user.profile, ImagerProfile) + + def test_user_model_has_str(self): + """Test user has a string method.""" + user = self.users[0] + self.assertIsInstance(str(user), str) + + # def test_user_model_has_attributes(self): diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index d6eacd6..295abbb 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -37,6 +37,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django-bootstrap3', 'imager_profile', 'imagersite' ] diff --git a/imagersite/requirements.pip b/imagersite/requirements.pip index 74feca4..779cab5 100644 --- a/imagersite/requirements.pip +++ b/imagersite/requirements.pip @@ -6,7 +6,6 @@ ipython==5.1.0 ipython-genutils==0.1.0 pexpect==4.2.1 pickleshare==0.7.4 -pkg-resources==0.0.0 prompt-toolkit==1.0.9 psycopg2==2.6.2 ptyprocess==0.5.1 diff --git a/requirements.pip b/requirements.pip index 54667b0..2436f19 100644 --- a/requirements.pip +++ b/requirements.pip @@ -1,13 +1,18 @@ decorator==4.0.11 Django==1.10.5 +django-bootstrap3==8.1.0 +factory-boy==2.8.1 +Faker==0.7.7 ipython==5.1.0 ipython-genutils==0.1.0 pexpect==4.2.1 pickleshare==0.7.4 +pkg-resources==0.0.0 prompt-toolkit==1.0.9 psycopg2==2.6.2 ptyprocess==0.5.1 Pygments==2.1.3 +python-dateutil==2.6.0 simplegeneric==0.8.1 six==1.10.0 traitlets==4.3.1 From e4121cbfbf4f8c4216b0568e28d132ddbefd91f2 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Wed, 18 Jan 2017 17:37:00 -0800 Subject: [PATCH 27/74] first pass HMAC templates --- .../imagersite/templates/registration/activate.html | 4 ++++ .../templates/registration/activation_complete.html | 4 ++++ .../templates/registration/activation_email.txt | 2 ++ .../templates/registration/activation_email_subject.txt | 1 + .../templates/registration/registration_complete.html | 4 ++++ .../templates/registration/registration_form.html | 8 ++++++++ 6 files changed, 23 insertions(+) create mode 100644 imagersite/imagersite/templates/registration/activate.html create mode 100644 imagersite/imagersite/templates/registration/activation_complete.html create mode 100644 imagersite/imagersite/templates/registration/activation_email.txt create mode 100644 imagersite/imagersite/templates/registration/activation_email_subject.txt create mode 100644 imagersite/imagersite/templates/registration/registration_complete.html create mode 100644 imagersite/imagersite/templates/registration/registration_form.html diff --git a/imagersite/imagersite/templates/registration/activate.html b/imagersite/imagersite/templates/registration/activate.html new file mode 100644 index 0000000..37bc407 --- /dev/null +++ b/imagersite/imagersite/templates/registration/activate.html @@ -0,0 +1,4 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

Activate Page

+{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/activation_complete.html b/imagersite/imagersite/templates/registration/activation_complete.html new file mode 100644 index 0000000..144d774 --- /dev/null +++ b/imagersite/imagersite/templates/registration/activation_complete.html @@ -0,0 +1,4 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

Activation complete

+{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/activation_email.txt b/imagersite/imagersite/templates/registration/activation_email.txt new file mode 100644 index 0000000..3c13308 --- /dev/null +++ b/imagersite/imagersite/templates/registration/activation_email.txt @@ -0,0 +1,2 @@ +Click here to register at imagersite: +http://{{ site.domain }}{% url "registration_activate" activation_key %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/activation_email_subject.txt b/imagersite/imagersite/templates/registration/activation_email_subject.txt new file mode 100644 index 0000000..42fd665 --- /dev/null +++ b/imagersite/imagersite/templates/registration/activation_email_subject.txt @@ -0,0 +1 @@ +Account Activation \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/registration_complete.html b/imagersite/imagersite/templates/registration/registration_complete.html new file mode 100644 index 0000000..37de4ff --- /dev/null +++ b/imagersite/imagersite/templates/registration/registration_complete.html @@ -0,0 +1,4 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

Registration Complete

+{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/registration_form.html b/imagersite/imagersite/templates/registration/registration_form.html new file mode 100644 index 0000000..d02acd9 --- /dev/null +++ b/imagersite/imagersite/templates/registration/registration_form.html @@ -0,0 +1,8 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +
+ {% csrf_token %} + {{ form.as_table }} + +
+{% endblock content %} \ No newline at end of file From f05f3665deeedcd8d6bd0be03ecc8dafddb05b94 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Wed, 18 Jan 2017 17:37:42 -0800 Subject: [PATCH 28/74] first pass HMAC templates --- imagersite/imagersite/settings.py | 8 +++++++- requirements.pip | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index 295abbb..78efdcc 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -115,7 +115,7 @@ LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +TIME_ZONE = 'America/Los_Angeles' USE_I18N = True @@ -128,3 +128,9 @@ # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' + + +# Registration Settings +ACCOUNT_ACTIVATION_DAYS = 3 +EMAIL_HOST = '127.0.0.1' +EMAIL_PORT = 1025 diff --git a/requirements.pip b/requirements.pip index 2436f19..08fffa9 100644 --- a/requirements.pip +++ b/requirements.pip @@ -1,13 +1,13 @@ decorator==4.0.11 Django==1.10.5 django-bootstrap3==8.1.0 +django-registration==2.2 factory-boy==2.8.1 Faker==0.7.7 ipython==5.1.0 ipython-genutils==0.1.0 pexpect==4.2.1 pickleshare==0.7.4 -pkg-resources==0.0.0 prompt-toolkit==1.0.9 psycopg2==2.6.2 ptyprocess==0.5.1 From 156f329199a423e4613cd6b2a61a69e3e65db4fe Mon Sep 17 00:00:00 2001 From: pasaunders Date: Wed, 18 Jan 2017 18:34:14 -0800 Subject: [PATCH 29/74] login logout and register seem to work --- imagersite/imagersite/settings.py | 5 ++++- .../templates/registration/login.html | 0 imagersite/imagersite/urls.py | 9 ++++++--- imagersite/imagersite/views.py | 2 +- imagersite/requirements.pip | 17 ----------------- 5 files changed, 11 insertions(+), 22 deletions(-) create mode 100644 imagersite/imagersite/templates/registration/login.html delete mode 100644 imagersite/requirements.pip diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index 78efdcc..ad52794 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -37,7 +37,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'django-bootstrap3', + 'bootstrap3', 'imager_profile', 'imagersite' ] @@ -134,3 +134,6 @@ ACCOUNT_ACTIVATION_DAYS = 3 EMAIL_HOST = '127.0.0.1' EMAIL_PORT = 1025 + +# Login/out settings +LOGIN_REDIRECT_URL='/' diff --git a/imagersite/imagersite/templates/registration/login.html b/imagersite/imagersite/templates/registration/login.html new file mode 100644 index 0000000..e69de29 diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index e5ded31..16ad8dc 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -1,4 +1,4 @@ -"""imagersite URL Configuration +"""imagersite URL Configuration. The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/ @@ -15,7 +15,8 @@ """ from django.conf.urls import include, url from django.contrib import ( - admin + admin, + auth ) from imagersite.views import ( home_view @@ -24,5 +25,7 @@ urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^$', home_view, name='homepage'), - url(r'^accounts/$', include('registration.backends.hmac.urls')), + url(r'^accounts/', include('registration.backends.hmac.urls')), + url(r'^login/', auth.views.login, name='login'), + url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout') ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index d5681d0..86279ce 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -1,6 +1,6 @@ """Views.""" from django.shortcuts import render -import registration.backends.hmac.views.RegistrationView +# from registration.backends.hmac.views import RegistrationView def home_view(request): diff --git a/imagersite/requirements.pip b/imagersite/requirements.pip deleted file mode 100644 index 779cab5..0000000 --- a/imagersite/requirements.pip +++ /dev/null @@ -1,17 +0,0 @@ -decorator==4.0.11 -Django==1.10.5 -factory-boy==2.8.1 -Faker==0.7.7 -ipython==5.1.0 -ipython-genutils==0.1.0 -pexpect==4.2.1 -pickleshare==0.7.4 -prompt-toolkit==1.0.9 -psycopg2==2.6.2 -ptyprocess==0.5.1 -Pygments==2.1.3 -python-dateutil==2.6.0 -simplegeneric==0.8.1 -six==1.10.0 -traitlets==4.3.1 -wcwidth==0.1.7 From 4496d4966d4b3b9e0f79f51ca9cee1bd267a0f8e Mon Sep 17 00:00:00 2001 From: pasaunders Date: Wed, 18 Jan 2017 18:34:44 -0800 Subject: [PATCH 30/74] readme change --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5152b0d..b1d6c64 100644 --- a/README.md +++ b/README.md @@ -35,4 +35,7 @@ Finally, run the server in order to server the app on `localhost` ``` Django will typically serve on port 8000, unless you specify otherwise. -You can access the locally-served site at the address `http://localhost:8000`. \ No newline at end of file +You can access the locally-served site at the address `http://localhost:8000`. + +Resources we used: +http://stackoverflow.com/questions/10180764/django-auth-login-problems \ No newline at end of file From 692f00c53a255e8f9ededd982baa7c34e9fc1566 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Wed, 18 Jan 2017 18:45:05 -0800 Subject: [PATCH 31/74] begin second app models --- imagersite/imager_images/__init__.py | 0 imagersite/imager_images/admin.py | 3 +++ imagersite/imager_images/apps.py | 5 +++++ imagersite/imager_images/migrations/__init__.py | 0 imagersite/imager_images/models.py | 4 ++++ imagersite/imager_images/tests.py | 3 +++ imagersite/imager_images/views.py | 3 +++ 7 files changed, 18 insertions(+) create mode 100644 imagersite/imager_images/__init__.py create mode 100644 imagersite/imager_images/admin.py create mode 100644 imagersite/imager_images/apps.py create mode 100644 imagersite/imager_images/migrations/__init__.py create mode 100644 imagersite/imager_images/models.py create mode 100644 imagersite/imager_images/tests.py create mode 100644 imagersite/imager_images/views.py diff --git a/imagersite/imager_images/__init__.py b/imagersite/imager_images/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/imagersite/imager_images/admin.py b/imagersite/imager_images/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/imagersite/imager_images/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/imagersite/imager_images/apps.py b/imagersite/imager_images/apps.py new file mode 100644 index 0000000..7afb70a --- /dev/null +++ b/imagersite/imager_images/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ImagerImagesConfig(AppConfig): + name = 'imager_images' diff --git a/imagersite/imager_images/migrations/__init__.py b/imagersite/imager_images/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/imagersite/imager_images/models.py b/imagersite/imager_images/models.py new file mode 100644 index 0000000..77a813f --- /dev/null +++ b/imagersite/imager_images/models.py @@ -0,0 +1,4 @@ +from django.db import models +from imagersite.models import ImagerProfile + +# Create your models here. \ No newline at end of file diff --git a/imagersite/imager_images/tests.py b/imagersite/imager_images/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/imagersite/imager_images/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/imagersite/imager_images/views.py b/imagersite/imager_images/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/imagersite/imager_images/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From c4fd524728b1ff009d0088f22137243040db52dd Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 18 Jan 2017 21:30:01 -0800 Subject: [PATCH 32/74] add MEDIA folder and the gitkeep for it and gitignore lines --- .gitignore | 4 ++++ imagersite/MEDIA/.gitkeep | 0 2 files changed, 4 insertions(+) create mode 100644 imagersite/MEDIA/.gitkeep diff --git a/.gitignore b/.gitignore index d6499d1..ac52e8b 100644 --- a/.gitignore +++ b/.gitignore @@ -92,3 +92,7 @@ ENV/ # Rope project settings .ropeproject + +# Ignore the files in the Media directory, but not the directory itself +imagersite/MEDIA/* +!imagersite/MEDIA/.gitkeep \ No newline at end of file diff --git a/imagersite/MEDIA/.gitkeep b/imagersite/MEDIA/.gitkeep new file mode 100644 index 0000000..e69de29 From 60c823ba769bd3149b7c12ac339c7404e087a1b0 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 18 Jan 2017 21:34:31 -0800 Subject: [PATCH 33/74] add fix for only add profile if created True --- imagersite/imager_profile/models.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index a9779a3..107d78f 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -62,5 +62,6 @@ def __str__(self): @receiver(post_save, sender=User) def make_profile_for_user(sender, instance, **kwargs): """Called when user is made and hooks that user to a profile.""" - new_profile = ImagerProfile(user=instance) - new_profile.save() + if kwargs["created"]: + new_profile = ImagerProfile(user=instance) + new_profile.save() From 34e633861926130e71f6b82e25e2f2d4c4703ea8 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 18 Jan 2017 21:37:30 -0800 Subject: [PATCH 34/74] add MEDIA_ROOT --- imagersite/imagersite/settings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index ad52794..7c00e4d 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -39,7 +39,8 @@ 'django.contrib.staticfiles', 'bootstrap3', 'imager_profile', - 'imagersite' + 'imagersite', + 'imager_images' ] MIDDLEWARE = [ @@ -137,3 +138,5 @@ # Login/out settings LOGIN_REDIRECT_URL='/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'MEDIA') +MEDIA_URL = "/media/" From 55444497e5f3ed97e6b4356d20de03552ad4d909 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 18 Jan 2017 21:38:19 -0800 Subject: [PATCH 35/74] add ability for admin to create model for images --- imagersite/imager_images/admin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imagersite/imager_images/admin.py b/imagersite/imager_images/admin.py index 8c38f3f..aae142c 100644 --- a/imagersite/imager_images/admin.py +++ b/imagersite/imager_images/admin.py @@ -1,3 +1,5 @@ from django.contrib import admin +from imager_images.models import Album, Photo -# Register your models here. +admin.site.register(Album) +admin.site.register(Photo) From 533e6e941bc2dd0273f6412785149e233e8c4d6f Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 18 Jan 2017 21:39:01 -0800 Subject: [PATCH 36/74] add photo and album models and migration --- .../imager_images/migrations/0001_initial.py | 61 +++++++++++++++++ imagersite/imager_images/models.py | 68 ++++++++++++++++++- 2 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 imagersite/imager_images/migrations/0001_initial.py diff --git a/imagersite/imager_images/migrations/0001_initial.py b/imagersite/imager_images/migrations/0001_initial.py new file mode 100644 index 0000000..1fa1ba8 --- /dev/null +++ b/imagersite/imager_images/migrations/0001_initial.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-19 05:16 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import imager_images.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Album', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=60)), + ('description', models.TextField(max_length=200)), + ('date_created', models.DateTimeField(auto_now_add=True)), + ('date_modified', models.DateTimeField(auto_now=True)), + ('date_published', models.DateTimeField(null=True)), + ('published', models.CharField(choices=[('private', 'private'), ('shared', 'shared'), ('public', 'public')], max_length=10)), + ], + ), + migrations.CreateModel( + name='Photo', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(upload_to=imager_images.models.image_path)), + ('title', models.CharField(max_length=60)), + ('description', models.TextField(max_length=120)), + ('date_uploaded', models.DateTimeField(auto_now_add=True)), + ('date_modified', models.DateTimeField(auto_now=True)), + ('date_published', models.DateTimeField(null=True)), + ('published', models.CharField(choices=[('private', 'private'), ('shared', 'shared'), ('public', 'public')], max_length=10)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddField( + model_name='album', + name='cover', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='albums_covered', to='imager_images.Photo'), + ), + migrations.AddField( + model_name='album', + name='photos', + field=models.ManyToManyField(related_name='albums', to='imager_images.Photo'), + ), + migrations.AddField( + model_name='album', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='albums', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/imagersite/imager_images/models.py b/imagersite/imager_images/models.py index 77a813f..7245076 100644 --- a/imagersite/imager_images/models.py +++ b/imagersite/imager_images/models.py @@ -1,4 +1,68 @@ +from __future__ import unicode_literals +from django.utils.encoding import python_2_unicode_compatible from django.db import models -from imagersite.models import ImagerProfile +from django.contrib.auth.models import User -# Create your models here. \ No newline at end of file +PUBLISHED_OPTIONS = ( + ("private", "private"), + ("shared", "shared"), + ("public", "public"), +) + + +def image_path(instance, file_name): + """Upload file to media root in user folder.""" + return 'user_{0}/{1}'.format(instance.user.id, file_name) + + +@python_2_unicode_compatible +class Photo(models.Model): + """Create Photo Model.""" + + user = models.ForeignKey( + User, + related_name='photos', + on_delete=models.CASCADE, + ) + image = models.ImageField(upload_to=image_path) + title = models.CharField(max_length=60) + description = models.TextField(max_length=120) + date_uploaded = models.DateTimeField(auto_now_add=True) + date_modified = models.DateTimeField(auto_now=True) + date_published = models.DateTimeField(null=True) + published = models.CharField(max_length=10, choices=PUBLISHED_OPTIONS) + + def __str__(self): + """Return string description of album.""" + return "{}: Photo belonging to {}".format(self.title, self.user) + + +@python_2_unicode_compatible +class Album(models.Model): + """Create Album Model.""" + + user = models.ForeignKey( + User, + related_name="albums", + on_delete=models.CASCADE, + ) + cover = models.ForeignKey( + "Photo", + null=True, + related_name="albums_covered" + ) + title = models.CharField(max_length=60) + description = models.TextField(max_length=200) + photos = models.ManyToManyField( + "Photo", + related_name="albums", + symmetrical=False + ) + date_created = models.DateTimeField(auto_now_add=True) + date_modified = models.DateTimeField(auto_now=True) + date_published = models.DateTimeField(null=True) + published = models.CharField(max_length=10, choices=PUBLISHED_OPTIONS) + + def __str__(self): + """Return String Representation of Album.""" + return "{}: Album belonging to {}".format(self.title, self.user) From 399d538e62e4832f8aae5b48336ababb99493894 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 18 Jan 2017 21:40:11 -0800 Subject: [PATCH 37/74] update requirements.pip with Pillow==4.0.0 --- requirements.pip | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements.pip b/requirements.pip index 08fffa9..d432505 100644 --- a/requirements.pip +++ b/requirements.pip @@ -6,8 +6,11 @@ factory-boy==2.8.1 Faker==0.7.7 ipython==5.1.0 ipython-genutils==0.1.0 +olefile==0.44 pexpect==4.2.1 pickleshare==0.7.4 +Pillow==4.0.0 +pkg-resources==0.0.0 prompt-toolkit==1.0.9 psycopg2==2.6.2 ptyprocess==0.5.1 From caf4ff7c1519f0cac43633df5e408ada3a03eefd Mon Sep 17 00:00:00 2001 From: pasaunders Date: Thu, 19 Jan 2017 18:44:19 -0800 Subject: [PATCH 38/74] new tests --- .../migrations/0003_auto_20170119_1823.py | 20 ++++++++++++++++ imagersite/imager_profile/models.py | 15 ++++++++++-- imagersite/imager_profile/tests.py | 23 +++++++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 imagersite/imager_profile/migrations/0003_auto_20170119_1823.py diff --git a/imagersite/imager_profile/migrations/0003_auto_20170119_1823.py b/imagersite/imager_profile/migrations/0003_auto_20170119_1823.py new file mode 100644 index 0000000..59498f7 --- /dev/null +++ b/imagersite/imager_profile/migrations/0003_auto_20170119_1823.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-20 02:23 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('imager_profile', '0002_auto_20170117_1828'), + ] + + operations = [ + migrations.AlterField( + model_name='imagerprofile', + name='photography_type', + field=models.CharField(blank=True, choices=[('portrait', 'Portrait'), ('landscape', 'Landscape'), ('bw', 'Black and White'), ('sport', 'Sport')], max_length=20, null=True), + ), + ] diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index 107d78f..0ea6baa 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -47,7 +47,18 @@ class ImagerProfile(models.Model): for_hire = models.BooleanField(default=False) travel_distance = models.IntegerField(null=True, blank=True) phone_number = models.CharField(max_length=15, null=True, blank=True) - photography_type = models.CharField(max_length=20, null=True, blank=True) + STYLE_CHOICES = [ + ('portrait', 'Portrait'), + ('landscape', 'Landscape'), + ('bw', 'Black and White'), + ('sport', 'Sport') + ] + photography_type = models.CharField( + max_length=20, + choices=STYLE_CHOICES, + null=True, + blank=True + ) @property def is_active(self): @@ -56,7 +67,7 @@ def is_active(self): def __str__(self): """Display user data as a string.""" - return "User: {}, Camera: {}, Address: {}, Phone number: {} For Hire? {}, Photography style: {}".format(self.user, self.camera_type, self.address, self.phone_number, self.for_hire, self.photography_type) + return "User: {}, Camera: {}, Address: {}, Phone number: {}, For Hire? {}, Photography style: {}".format(self.user, self.camera_type, self.address, self.phone_number, self.for_hire, self.photography_type) @receiver(post_save, sender=User) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index 35186c3..37b8ac1 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -1,5 +1,5 @@ """Tests for the imager_profile app.""" -from django.test import TestCase +from django.test import TestCase, Client, RequestFactory from django.contrib.auth.models import User from imager_profile.models import ImagerProfile import factory @@ -47,4 +47,23 @@ def test_user_model_has_str(self): user = self.users[0] self.assertIsInstance(str(user), str) - # def test_user_model_has_attributes(self): + def test_user_model_has_attributes(self): + """Test user attributes are present.""" + pass + + def test_active_users_counted(self): + """Test acttive user count meets expectations.""" + self.assertTrue(ImagerProfile.active.count() == User.objects.count()) + + def test_inactive_users_not_counted(self): + """Test inactive users not included with active users.""" + deactivated_user = self.users[0] + deactivated_user.is_active = False + deactivated_user.save() + self.assertTrue(ImagerProfile.active.count() == User.objects.count() - 1) + + + +class frontend_test_cases(TestCase): + """Test the frontend of the imager_profile site.""" + pass From b70a7b6b62603031329f5986f025f8e7060ab902 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Thu, 19 Jan 2017 22:49:29 -0800 Subject: [PATCH 39/74] extend tests, needs debugging --- imagersite/imager_profile/tests.py | 127 +++++++++++++++++++++++++---- 1 file changed, 109 insertions(+), 18 deletions(-) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index 37b8ac1..0ad5b68 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -5,26 +5,27 @@ import factory -class ProfileTestCase(TestCase): - """The Profile Model test runner.""" +class UserFactory(factory.django.DjangoModelFactory): + """Makes users.""" - class UserFactory(factory.django.DjangoModelFactory): - """Makes users.""" + class Meta: + """Meta.""" - class Meta: - """Meta.""" + model = User - model = User + username = factory.Sequence(lambda n: "The Chosen {}".format(n)) + email = factory.LazyAttribute( + lambda x: "{}@foo.com".format(x.username.replace(" ", "")) + ) - username = factory.Sequence(lambda n: "The Chosen {}".format(n)) - email = factory.LazyAttribute( - lambda x: "{}@foo.com".format(x.username.replace(" ", "")) - ) + +class ProfileTestCase(TestCase): + """The Profile Model test runner.""" def setUp(self): """The appropriate setup for the appropriate test.""" self.foo = "bar" - self.users = [self.UserFactory.create() for i in range(20)] + self.users = [UserFactory.create() for i in range(20)] def test_profile_is_made_when_user_is_saved(self): """Test profile is made when user is saved.""" @@ -47,9 +48,9 @@ def test_user_model_has_str(self): user = self.users[0] self.assertIsInstance(str(user), str) - def test_user_model_has_attributes(self): - """Test user attributes are present.""" - pass + # def test_user_model_has_attributes(self): + # """Test user attributes are present.""" + # pass def test_active_users_counted(self): """Test acttive user count meets expectations.""" @@ -63,7 +64,97 @@ def test_inactive_users_not_counted(self): self.assertTrue(ImagerProfile.active.count() == User.objects.count() - 1) - -class frontend_test_cases(TestCase): +class FrontendTestCases(TestCase): """Test the frontend of the imager_profile site.""" - pass + + def setUp(self): + """Set up client and request factory.""" + self.client = Client() + self.request = RequestFactory() + + def test_home_view_status(self): + """Test home view has 200 status.""" + from imagersite.views import home_view + req = self.request.get("/route") + response = home_view(req) + self.assertTrue(response.status_code == 200) + + def test_home_route_status(self): + """Test home route has 200 status.""" + response = self.client.get("/") + self.assertTrue(response.status_code == 200) + + def test_home_route_templates(self): + """Test the home route templates are correct.""" + response = self.client.get("/") + self.assertTemplateUsed(response, "imagersite/base.html") + self.assertTemplateUsed(response, "imagersite/home.html") + + def test_login_redirect_code(self): + """Test built-in login route redirects properly.""" + user_register = UserFactory.create() + user_register.username = "username" + user_register.password = "potatoes" + user_register.save() + response = self.client.post("/login/", { + "username": user_register.username, + "password": "potatoes" + + }) + self.assertTrue(response.status_code == 302) + + def test_login_redirect_home(self): + """Test built-in login route redirects to home.""" + user_register = UserFactory.create() + user_register.username = "username2" + user_register.password = "potatoes2" + user_register.save() + response = self.client.post("/login/", { + "username": user_register.username, + "password": "potatoes" + }, follow=True) + self.assertTrue(response.redirect_chain[0][0] == '/') + + def test_register_user(self): + """Test that tests can register users.""" + self.assertTrue(User.objects.count() == 0) + self.client.post("/registration/register/", { + "username": "Sir_Joseph", + "email": "e@mail.com", + "password1": "rutabega", + "password2": "rutabega" + }) + self.assertTrue(User.objects.count() == 1) + + def test_new_user_inactive(self): + """Test django-created user starts as inactive.""" + self.client.post("/registration/register/", { + "username": "Sir_Joseph", + "email": "e@mail.com", + "password1": "rutabega", + "password2": "rutabega" + }) + inactive_user = User.objects.first() + self.assertFalse(inactive_user.is_active) + + def test_registration_redirect(self): + """Test redirect on registration.""" + response = self.client.post("/registration/register/", { + "username": "Sir_Joseph", + "email": "e@mail.com", + "password1": "rutabega", + "password2": "rutabega" + }) + self.assertTrue(response.status_code == 302) + + def test_registration_reidrect_home(self): + """Test registration redirects home.""" + response = self.client.post("/registration/register/", { + "username": "Sir_Joseph", + "email": "e@mail.com", + "password1": "rutabega", + "password2": "rutabega" + }, follow=True) + self.assertTrue( + response.redirect_chain[0][0] == "/registration/register/complete/" + ) From f7066eeea153d596c1287e6047fad2a4ba87ed84 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Fri, 20 Jan 2017 18:21:51 -0800 Subject: [PATCH 40/74] new templates, new login page. --- .../imagersite/templates/imagersite/base.html | 9 ++++++++- .../imagersite/templates/imagersite/library.html | 4 ++++ .../imagersite/templates/imagersite/profile.html | 4 ++++ .../registration/activation_complete.html | 2 +- .../imagersite/templates/registration/login.html | 14 ++++++++++++++ imagersite/imagersite/urls.py | 2 +- imagersite/imagersite/views.py | 7 +++++++ 7 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 imagersite/imagersite/templates/imagersite/library.html create mode 100644 imagersite/imagersite/templates/imagersite/profile.html diff --git a/imagersite/imagersite/templates/imagersite/base.html b/imagersite/imagersite/templates/imagersite/base.html index cfea42a..4ea014d 100644 --- a/imagersite/imagersite/templates/imagersite/base.html +++ b/imagersite/imagersite/templates/imagersite/base.html @@ -4,6 +4,13 @@ App -{% block content %}{% endblock %} +{% if user.is_authenticated %} + Logout + Your Profile +{% else %} + Login +{% endif %} +{% block content %} +{% endblock %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/imagersite/library.html b/imagersite/imagersite/templates/imagersite/library.html new file mode 100644 index 0000000..4ecc0ad --- /dev/null +++ b/imagersite/imagersite/templates/imagersite/library.html @@ -0,0 +1,4 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

Library Page

+{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/imagersite/profile.html b/imagersite/imagersite/templates/imagersite/profile.html new file mode 100644 index 0000000..3126cf5 --- /dev/null +++ b/imagersite/imagersite/templates/imagersite/profile.html @@ -0,0 +1,4 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

Profile Page

+{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/activation_complete.html b/imagersite/imagersite/templates/registration/activation_complete.html index 144d774..fcc3f0c 100644 --- a/imagersite/imagersite/templates/registration/activation_complete.html +++ b/imagersite/imagersite/templates/registration/activation_complete.html @@ -1,4 +1,4 @@ {% extends 'imagersite/base.html' %} {% block content %} -

Activation complete

+

Activation complete, welcome to imagersite

{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/login.html b/imagersite/imagersite/templates/registration/login.html index e69de29..010e14f 100644 --- a/imagersite/imagersite/templates/registration/login.html +++ b/imagersite/imagersite/templates/registration/login.html @@ -0,0 +1,14 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +{% if form.errors %} +

Your Username and password didn't match. Please try again.

+{% endif %} +
+ {% csrf_token %} + {{ form.username.label_tag }} + {{ form.username }} + {{ form.password.label_tag }} + {{ form.password }} + +
+{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index 16ad8dc..9883395 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -26,6 +26,6 @@ url(r'^admin/', admin.site.urls), url(r'^$', home_view, name='homepage'), url(r'^accounts/', include('registration.backends.hmac.urls')), - url(r'^login/', auth.views.login, name='login'), + url(r'^login/', auth.views.login, {'next_page': '/'}, name='login'), url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout') ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index 86279ce..1a6ddea 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -8,3 +8,10 @@ def home_view(request): return render(request, "imagersite/home.html" ) + + +def profile_view(request): + """The user profile view.""" + return render(request, + "imagersite/profile.html" + ) From 94ae0ec15199d4e9473d4eeb1aaf5b35ca6733be Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Sat, 21 Jan 2017 16:07:05 -0800 Subject: [PATCH 41/74] login redirect to profile page, if user not logged in /profile/ redirects to login --- .../migrations/0004_imagerprofile_address.py | 20 +++++++++++++++++++ imagersite/imager_profile/models.py | 2 +- .../templates/imagersite/profile.html | 13 ++++++++++-- .../templates/registration/login.html | 1 + imagersite/imagersite/urls.py | 8 +++++--- imagersite/imagersite/views.py | 5 ++++- 6 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 imagersite/imager_profile/migrations/0004_imagerprofile_address.py diff --git a/imagersite/imager_profile/migrations/0004_imagerprofile_address.py b/imagersite/imager_profile/migrations/0004_imagerprofile_address.py new file mode 100644 index 0000000..3df6819 --- /dev/null +++ b/imagersite/imager_profile/migrations/0004_imagerprofile_address.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-22 00:01 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('imager_profile', '0003_auto_20170119_1823'), + ] + + operations = [ + migrations.AddField( + model_name='imagerprofile', + name='address', + field=models.CharField(blank=True, max_length=40, null=True), + ), + ] diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index 0ea6baa..68f70df 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -41,7 +41,7 @@ class ImagerProfile(models.Model): null=True, blank=True ) - address = models.CharField(max_length=40, null=True, blank=True), + address = models.CharField(max_length=40, null=True, blank=True) bio = models.TextField(default="") personal_website = models.URLField(default="") for_hire = models.BooleanField(default=False) diff --git a/imagersite/imagersite/templates/imagersite/profile.html b/imagersite/imagersite/templates/imagersite/profile.html index 3126cf5..273b178 100644 --- a/imagersite/imagersite/templates/imagersite/profile.html +++ b/imagersite/imagersite/templates/imagersite/profile.html @@ -1,4 +1,13 @@ {% extends 'imagersite/base.html' %} {% block content %} -

Profile Page

-{% endblock content %} \ No newline at end of file +
+

Welcome {{user.username}}!

+
    +
  • Name: {{user.first_name}} {{user.last_name}}
  • +
  • Location: {{user.profile.address}}
  • +
  • Camera: {{user.profile.camera_type}}
  • +
  • Photos Uploaded: {{user.photos.count}} +
  • Albums Created: {{user.albums.count}} +
+
+{% endblock %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/login.html b/imagersite/imagersite/templates/registration/login.html index 010e14f..2134ecd 100644 --- a/imagersite/imagersite/templates/registration/login.html +++ b/imagersite/imagersite/templates/registration/login.html @@ -10,5 +10,6 @@ {{ form.password.label_tag }} {{ form.password }} + {% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index 9883395..4381c08 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -19,13 +19,15 @@ auth ) from imagersite.views import ( - home_view + home_view, + profile_view ) urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^$', home_view, name='homepage'), url(r'^accounts/', include('registration.backends.hmac.urls')), - url(r'^login/', auth.views.login, {'next_page': '/'}, name='login'), - url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout') + url(r'^login/', auth.views.login, name='login'), + url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout'), + url(r'^profile/', profile_view, name='profile') ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index 1a6ddea..7c7ea07 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -1,6 +1,7 @@ """Views.""" from django.shortcuts import render # from registration.backends.hmac.views import RegistrationView +from django.contrib.auth.decorators import login_required def home_view(request): @@ -10,8 +11,10 @@ def home_view(request): ) +@login_required(login_url='/accounts/login/') def profile_view(request): """The user profile view.""" return render(request, - "imagersite/profile.html" + "imagersite/profile.html", + {"user": request.user} ) From a2ee6617c13cd5fe8a6a3ea48a7e85bf45f0884e Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Sat, 21 Jan 2017 16:41:47 -0800 Subject: [PATCH 42/74] add more to profile template --- imagersite/imagersite/templates/imagersite/profile.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/imagersite/imagersite/templates/imagersite/profile.html b/imagersite/imagersite/templates/imagersite/profile.html index 273b178..1fbc4cd 100644 --- a/imagersite/imagersite/templates/imagersite/profile.html +++ b/imagersite/imagersite/templates/imagersite/profile.html @@ -4,6 +4,12 @@

Welcome {{user.username}}!

  • Name: {{user.first_name}} {{user.last_name}}
  • +
  • Bio: {{user.profile.bio}}
  • +
  • Website: {{user.profile.personal_website}}
  • +
  • For Hire: {{user.profile.for_hire}}
  • +
  • Travel Distance: {{user.profile.travel_distance}} Miles
  • +
  • Phone Number: {{user.profile.phone_number}}
  • +
  • Photography Type: {{user.profile.photography_type}}
  • Location: {{user.profile.address}}
  • Camera: {{user.profile.camera_type}}
  • Photos Uploaded: {{user.photos.count}} From 9d764c2f47176caf8f563cd3c51626061c9e9b0d Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Sat, 21 Jan 2017 17:44:19 -0800 Subject: [PATCH 43/74] add so that /profile/ is current logged in user and /profile/ show public profile --- .../migrations/0005_auto_20170121_1732.py | 20 +++++++++++++++++++ imagersite/imager_profile/models.py | 8 ++++---- .../templates/imagersite/profile.html | 7 +++++-- imagersite/imagersite/urls.py | 4 +++- imagersite/imagersite/views.py | 15 +++++++++++++- 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 imagersite/imager_profile/migrations/0005_auto_20170121_1732.py diff --git a/imagersite/imager_profile/migrations/0005_auto_20170121_1732.py b/imagersite/imager_profile/migrations/0005_auto_20170121_1732.py new file mode 100644 index 0000000..7411c93 --- /dev/null +++ b/imagersite/imager_profile/migrations/0005_auto_20170121_1732.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-22 01:32 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('imager_profile', '0004_imagerprofile_address'), + ] + + operations = [ + migrations.AlterField( + model_name='imagerprofile', + name='photography_type', + field=models.CharField(blank=True, choices=[('Portrait', 'Portrait'), ('Landscape', 'Landscape'), ('Black and White', 'Black and White'), ('Sport', 'Sport')], max_length=20, null=True), + ), + ] diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index 68f70df..3256581 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -48,10 +48,10 @@ class ImagerProfile(models.Model): travel_distance = models.IntegerField(null=True, blank=True) phone_number = models.CharField(max_length=15, null=True, blank=True) STYLE_CHOICES = [ - ('portrait', 'Portrait'), - ('landscape', 'Landscape'), - ('bw', 'Black and White'), - ('sport', 'Sport') + ('Portrait', 'Portrait'), + ('Landscape', 'Landscape'), + ('Black and White', 'Black and White'), + ('Sport', 'Sport') ] photography_type = models.CharField( max_length=20, diff --git a/imagersite/imagersite/templates/imagersite/profile.html b/imagersite/imagersite/templates/imagersite/profile.html index 1fbc4cd..136fb4a 100644 --- a/imagersite/imagersite/templates/imagersite/profile.html +++ b/imagersite/imagersite/templates/imagersite/profile.html @@ -4,16 +4,19 @@

    Welcome {{user.username}}!

    • Name: {{user.first_name}} {{user.last_name}}
    • +
    • Email: {{user.email}}
    • Bio: {{user.profile.bio}}
    • -
    • Website: {{user.profile.personal_website}}
    • +
    • Website: {{user.profile.personal_website}}
    • For Hire: {{user.profile.for_hire}}
    • Travel Distance: {{user.profile.travel_distance}} Miles
    • Phone Number: {{user.profile.phone_number}}
    • Photography Type: {{user.profile.photography_type}}
    • -
    • Location: {{user.profile.address}}
    • Camera: {{user.profile.camera_type}}
    • + {% ifequal request.get_full_path '/profile/' %} +
    • Location: {{user.profile.address}}
    • Photos Uploaded: {{user.photos.count}}
    • Albums Created: {{user.albums.count}} + {% endifequal %}
    {% endblock %} \ No newline at end of file diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index 4381c08..da5c540 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -20,7 +20,8 @@ ) from imagersite.views import ( home_view, - profile_view + profile_view, + public_profile ) urlpatterns = [ @@ -29,5 +30,6 @@ url(r'^accounts/', include('registration.backends.hmac.urls')), url(r'^login/', auth.views.login, name='login'), url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout'), + url(r'^profile/(?P\w+)', public_profile, name='public_profile'), url(r'^profile/', profile_view, name='profile') ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index 7c7ea07..6c293cc 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -2,6 +2,7 @@ from django.shortcuts import render # from registration.backends.hmac.views import RegistrationView from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User def home_view(request): @@ -14,7 +15,19 @@ def home_view(request): @login_required(login_url='/accounts/login/') def profile_view(request): """The user profile view.""" + user = {"user": request.user} + user['public'] = False return render(request, "imagersite/profile.html", - {"user": request.user} + user + ) + + +def public_profile(request, username): + """Public profile view.""" + user = {"user": User.objects.get(username=username)} + user['public'] = True + return render(request, + "imagersite/profile.html", + user ) From 2b026a5f94dec8ade9ebe036629865d6cc97623e Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Sat, 21 Jan 2017 17:45:18 -0800 Subject: [PATCH 44/74] remove not needed any more public key dict --- imagersite/imagersite/views.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index 6c293cc..d599fe1 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -15,19 +15,15 @@ def home_view(request): @login_required(login_url='/accounts/login/') def profile_view(request): """The user profile view.""" - user = {"user": request.user} - user['public'] = False return render(request, "imagersite/profile.html", - user + {"user": request.user} ) def public_profile(request, username): """Public profile view.""" - user = {"user": User.objects.get(username=username)} - user['public'] = True return render(request, "imagersite/profile.html", - user + {"user": User.objects.get(username=username)} ) From ed38dd5c8f1fd8ffd4915fc1725ee7249e4d5423 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Sat, 21 Jan 2017 18:56:38 -0800 Subject: [PATCH 45/74] moved profile to urls and view to their correct place --- .../templates/imager_profile}/library.html | 0 .../templates/imager_profile}/profile.html | 2 +- imagersite/imager_profile/urls.py | 8 ++++++++ imagersite/imager_profile/views.py | 20 ++++++++++++++++++- imagersite/imagersite/urls.py | 7 ++----- imagersite/imagersite/views.py | 20 ------------------- 6 files changed, 30 insertions(+), 27 deletions(-) rename imagersite/{imagersite/templates/imagersite => imager_profile/templates/imager_profile}/library.html (100%) rename imagersite/{imagersite/templates/imagersite => imager_profile/templates/imager_profile}/profile.html (91%) create mode 100644 imagersite/imager_profile/urls.py diff --git a/imagersite/imagersite/templates/imagersite/library.html b/imagersite/imager_profile/templates/imager_profile/library.html similarity index 100% rename from imagersite/imagersite/templates/imagersite/library.html rename to imagersite/imager_profile/templates/imager_profile/library.html diff --git a/imagersite/imagersite/templates/imagersite/profile.html b/imagersite/imager_profile/templates/imager_profile/profile.html similarity index 91% rename from imagersite/imagersite/templates/imagersite/profile.html rename to imagersite/imager_profile/templates/imager_profile/profile.html index 136fb4a..0e7098f 100644 --- a/imagersite/imagersite/templates/imagersite/profile.html +++ b/imagersite/imager_profile/templates/imager_profile/profile.html @@ -4,7 +4,7 @@

    Welcome {{user.username}}!

    • Name: {{user.first_name}} {{user.last_name}}
    • -
    • Email: {{user.email}}
    • +
    • Email: {{user.email}}
    • Bio: {{user.profile.bio}}
    • Website: {{user.profile.personal_website}}
    • For Hire: {{user.profile.for_hire}}
    • diff --git a/imagersite/imager_profile/urls.py b/imagersite/imager_profile/urls.py new file mode 100644 index 0000000..faa8a1e --- /dev/null +++ b/imagersite/imager_profile/urls.py @@ -0,0 +1,8 @@ +"""Profile urls.""" +from django.conf.urls import url +from .views import public_profile, profile_view + +urlpatterns = [ + url(r'^(?P\w+)', public_profile, name='public_profile'), + url(r'^$', profile_view, name='private_profile') +] diff --git a/imagersite/imager_profile/views.py b/imagersite/imager_profile/views.py index 91ea44a..18d42d0 100644 --- a/imagersite/imager_profile/views.py +++ b/imagersite/imager_profile/views.py @@ -1,3 +1,21 @@ +"""Profile views.""" from django.shortcuts import render +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User -# Create your views here. + +@login_required(login_url='/accounts/login/') +def profile_view(request): + """The user profile view.""" + return render(request, + "imager_profile/profile.html", + {"user": request.user} + ) + + +def public_profile(request, username): + """Public profile view.""" + return render(request, + "imager_profile/profile.html", + {"user": User.objects.get(username=username)} + ) diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index da5c540..448f33b 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -19,9 +19,7 @@ auth ) from imagersite.views import ( - home_view, - profile_view, - public_profile + home_view ) urlpatterns = [ @@ -30,6 +28,5 @@ url(r'^accounts/', include('registration.backends.hmac.urls')), url(r'^login/', auth.views.login, name='login'), url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout'), - url(r'^profile/(?P\w+)', public_profile, name='public_profile'), - url(r'^profile/', profile_view, name='profile') + url(r'^profile/', include('imager_profile.urls')) ] diff --git a/imagersite/imagersite/views.py b/imagersite/imagersite/views.py index d599fe1..c0ce2a7 100644 --- a/imagersite/imagersite/views.py +++ b/imagersite/imagersite/views.py @@ -1,8 +1,5 @@ """Views.""" from django.shortcuts import render -# from registration.backends.hmac.views import RegistrationView -from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User def home_view(request): @@ -10,20 +7,3 @@ def home_view(request): return render(request, "imagersite/home.html" ) - - -@login_required(login_url='/accounts/login/') -def profile_view(request): - """The user profile view.""" - return render(request, - "imagersite/profile.html", - {"user": request.user} - ) - - -def public_profile(request, username): - """Public profile view.""" - return render(request, - "imagersite/profile.html", - {"user": User.objects.get(username=username)} - ) From b1d348e2a3ccb6b004d891d0283fb84afb6f4f54 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Mon, 23 Jan 2017 11:19:51 -0800 Subject: [PATCH 46/74] add photo and photos routes --- .../templates/imager_images/photo.html | 5 +++++ .../templates/imager_images/photos.html | 15 +++++++++++++ imagersite/imager_images/urls.py | 8 +++++++ imagersite/imager_images/views.py | 21 ++++++++++++++++++- .../imagersite/templates/imagersite/base.html | 2 ++ imagersite/imagersite/urls.py | 7 +++++-- 6 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 imagersite/imager_images/templates/imager_images/photo.html create mode 100644 imagersite/imager_images/templates/imager_images/photos.html create mode 100644 imagersite/imager_images/urls.py diff --git a/imagersite/imager_images/templates/imager_images/photo.html b/imagersite/imager_images/templates/imager_images/photo.html new file mode 100644 index 0000000..c3b988c --- /dev/null +++ b/imagersite/imager_images/templates/imager_images/photo.html @@ -0,0 +1,5 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

      Photo

      + +{% endblock content %} \ No newline at end of file diff --git a/imagersite/imager_images/templates/imager_images/photos.html b/imagersite/imager_images/templates/imager_images/photos.html new file mode 100644 index 0000000..64cb8d0 --- /dev/null +++ b/imagersite/imager_images/templates/imager_images/photos.html @@ -0,0 +1,15 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

      Photos

      +
      +{% for photo in photos %} + +{% endfor %} +
      + +{% endblock content %} \ No newline at end of file diff --git a/imagersite/imager_images/urls.py b/imagersite/imager_images/urls.py new file mode 100644 index 0000000..a89e643 --- /dev/null +++ b/imagersite/imager_images/urls.py @@ -0,0 +1,8 @@ +"""Images urls.""" +from django.conf.urls import url +from .views import photo_view, all_photos + +urlpatterns = [ + url(r'^photos/(?P\d+)', photo_view, name='public_profile'), + url(r'^photos/$', all_photos, name='private_profile') # display all of the public photos that have been uploaded +] diff --git a/imagersite/imager_images/views.py b/imagersite/imager_images/views.py index 91ea44a..ea65f27 100644 --- a/imagersite/imager_images/views.py +++ b/imagersite/imager_images/views.py @@ -1,3 +1,22 @@ +"""Views for images.""" from django.shortcuts import render +from imager_images.models import Photo +from django.http import HttpResponse -# Create your views here. + +def photo_view(request, photo_id): + """Render individual image by id.""" + photo = Photo.objects.get(id=photo_id) + if photo.published != 'private' or photo.user.username == request.user.username: + return render(request, 'imager_images/photo.html', {"photo": photo}) + return HttpResponse('Unauthorized', status=401) + + +def all_photos(request): + """Render all photos in app.""" + public_photos = [] + photos = Photo.objects.all() + for photo in photos: + if photo.published != 'private' or photo.user.username == request.user.username: + public_photos.append(photo) + return render(request, 'imager_images/photos.html', {"photos": public_photos}) diff --git a/imagersite/imagersite/templates/imagersite/base.html b/imagersite/imagersite/templates/imagersite/base.html index 4ea014d..08b3e08 100644 --- a/imagersite/imagersite/templates/imagersite/base.html +++ b/imagersite/imagersite/templates/imagersite/base.html @@ -2,6 +2,8 @@ App + + {% if user.is_authenticated %} diff --git a/imagersite/imagersite/urls.py b/imagersite/imagersite/urls.py index 448f33b..1273391 100644 --- a/imagersite/imagersite/urls.py +++ b/imagersite/imagersite/urls.py @@ -21,6 +21,8 @@ from imagersite.views import ( home_view ) +from django.conf import settings +from django.conf.urls.static import static urlpatterns = [ url(r'^admin/', admin.site.urls), @@ -28,5 +30,6 @@ url(r'^accounts/', include('registration.backends.hmac.urls')), url(r'^login/', auth.views.login, name='login'), url(r'^logout/', auth.views.logout, {'next_page': '/'}, name='logout'), - url(r'^profile/', include('imager_profile.urls')) -] + url(r'^profile/', include('imager_profile.urls')), + url(r'^images/', include('imager_images.urls')) +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) From 9024b296ad269427bbe011f064beb88df22379a7 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Mon, 23 Jan 2017 11:53:23 -0800 Subject: [PATCH 47/74] add some bootstrap --- .../imagersite/templates/imagersite/base.html | 28 +++++++++++++++---- .../templates/registration/login.html | 11 ++------ .../registration/registration_form.html | 5 ++-- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/imagersite/imagersite/templates/imagersite/base.html b/imagersite/imagersite/templates/imagersite/base.html index 08b3e08..8d0805d 100644 --- a/imagersite/imagersite/templates/imagersite/base.html +++ b/imagersite/imagersite/templates/imagersite/base.html @@ -4,14 +4,30 @@ App + {% load bootstrap3 %} + {% bootstrap_css %} + {% bootstrap_javascript %} -{% if user.is_authenticated %} - Logout - Your Profile -{% else %} - Login -{% endif %} + {% block content %} {% endblock %} diff --git a/imagersite/imagersite/templates/registration/login.html b/imagersite/imagersite/templates/registration/login.html index 2134ecd..e9c237a 100644 --- a/imagersite/imagersite/templates/registration/login.html +++ b/imagersite/imagersite/templates/registration/login.html @@ -1,15 +1,10 @@ {% extends 'imagersite/base.html' %} {% block content %} -{% if form.errors %} -

      Your Username and password didn't match. Please try again.

      -{% endif %} +{% load bootstrap3 %}
      + {% bootstrap_form form %} {% csrf_token %} - {{ form.username.label_tag }} - {{ form.username }} - {{ form.password.label_tag }} - {{ form.password }} - + {% bootstrap_button "Login" button_type="submit" button_class="btn-primary" %}
      {% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/registration/registration_form.html b/imagersite/imagersite/templates/registration/registration_form.html index d02acd9..46c770c 100644 --- a/imagersite/imagersite/templates/registration/registration_form.html +++ b/imagersite/imagersite/templates/registration/registration_form.html @@ -1,8 +1,9 @@ {% extends 'imagersite/base.html' %} {% block content %} +{% load bootstrap3 %}
      + {% bootstrap_form form %} {% csrf_token %} - {{ form.as_table }} - + {% bootstrap_button "Register" button_type="submit" button_class="btn-primary" %}
      {% endblock content %} \ No newline at end of file From 1aefdf160d1adff5ab413592452259423e4f0dc7 Mon Sep 17 00:00:00 2001 From: pasaunders Date: Mon, 23 Jan 2017 22:14:35 -0800 Subject: [PATCH 48/74] album routes and views, tested manually. tests sketched out but none complete. --- imagersite/imager_images/models.py | 2 +- .../templates/imager_images/album.html | 16 +++++ .../templates/imager_images/albums.html | 15 ++++ imagersite/imager_images/tests.py | 68 ++++++++++++++++++- imagersite/imager_images/urls.py | 6 +- imagersite/imager_images/views.py | 28 +++++++- imagersite/imager_profile/tests.py | 1 - .../templates/imagersite/album.html | 4 ++ 8 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 imagersite/imager_images/templates/imager_images/album.html create mode 100644 imagersite/imager_images/templates/imager_images/albums.html create mode 100644 imagersite/imagersite/templates/imagersite/album.html diff --git a/imagersite/imager_images/models.py b/imagersite/imager_images/models.py index 7245076..2767fed 100644 --- a/imagersite/imager_images/models.py +++ b/imagersite/imager_images/models.py @@ -33,7 +33,7 @@ class Photo(models.Model): published = models.CharField(max_length=10, choices=PUBLISHED_OPTIONS) def __str__(self): - """Return string description of album.""" + """Return string description of photo.""" return "{}: Photo belonging to {}".format(self.title, self.user) diff --git a/imagersite/imager_images/templates/imager_images/album.html b/imagersite/imager_images/templates/imager_images/album.html new file mode 100644 index 0000000..0f7c28d --- /dev/null +++ b/imagersite/imager_images/templates/imager_images/album.html @@ -0,0 +1,16 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

      Your Album:

      +
      + +{% for photo in album.photos %} + +{% endfor %} +
      + +{% endblock content %} \ No newline at end of file diff --git a/imagersite/imager_images/templates/imager_images/albums.html b/imagersite/imager_images/templates/imager_images/albums.html new file mode 100644 index 0000000..cc73718 --- /dev/null +++ b/imagersite/imager_images/templates/imager_images/albums.html @@ -0,0 +1,15 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

      Public Albums

      +
      +{% for album in albums %} + +{% endfor %} +
      + +{% endblock content %} \ No newline at end of file diff --git a/imagersite/imager_images/tests.py b/imagersite/imager_images/tests.py index 7ce503c..4f2bba7 100644 --- a/imagersite/imager_images/tests.py +++ b/imagersite/imager_images/tests.py @@ -1,3 +1,69 @@ -from django.test import TestCase +from django.test import TestCase, Client, RequestFactory +from django.contrib.auth.models import User +from imager_images.models import Photo, Album +import factory # Create your tests here. + + +class UserFactory(factory.django.DjangoModelFactory): + """Makes users.""" + + class Meta: + """Meta.""" + + model = User + + username = factory.Sequence(lambda n: "The Chosen {}".format(n)) + email = factory.LazyAttribute( + lambda x: "{}@foo.com".format(x.username.replace(" ", "")) + ) + + +class PhotoTestCase(TestCase): + """Photo model and view tests.""" + + def setUp(self): + """Set up users for photo tests.""" + self.users = [UserFactory.create() for i in range(20)] + """ + To test: + photo model is built + photos are associated with users + assigning values to photo attributes + presence of string method + """ + + +class AlbumTestCase(TestCase): + """Album model and view tests.""" + + def setUp(self): + """Set up users for photo tests.""" + self.users = [UserFactory.create() for i in range(20)] + + """ + To test: + album model is built + albums are associated with users + assigning values to album attributes + presence of string method + photo creation and modified date/times are now + """ + + +class FrontEndTestCase(TestCase): + """Front end tests.""" + + def setUp(self): + """Set up users for front end tests.""" + self.users = [UserFactory.create() for i in range(20)] + + """ + To test: + Views return 200 + Routes return 200 + all four templates are used + albums are visible in albums.html + correct number of photos and albums are visible + """ \ No newline at end of file diff --git a/imagersite/imager_images/urls.py b/imagersite/imager_images/urls.py index a89e643..d37541b 100644 --- a/imagersite/imager_images/urls.py +++ b/imagersite/imager_images/urls.py @@ -1,8 +1,10 @@ """Images urls.""" from django.conf.urls import url -from .views import photo_view, all_photos +from .views import photo_view, all_photos, single_album, all_albums urlpatterns = [ url(r'^photos/(?P\d+)', photo_view, name='public_profile'), - url(r'^photos/$', all_photos, name='private_profile') # display all of the public photos that have been uploaded + url(r'^photos/$', all_photos, name='private_profile'), # display all of the public photos that have been uploaded + url(r'^albums/(?P[-\w]+)', single_album, name='single_album'), # display a single selected album + url(r'^albums/?', all_albums, name='all_albums') ] diff --git a/imagersite/imager_images/views.py b/imagersite/imager_images/views.py index ea65f27..fa482c4 100644 --- a/imagersite/imager_images/views.py +++ b/imagersite/imager_images/views.py @@ -1,6 +1,6 @@ """Views for images.""" from django.shortcuts import render -from imager_images.models import Photo +from imager_images.models import Photo, Album from django.http import HttpResponse @@ -20,3 +20,29 @@ def all_photos(request): if photo.published != 'private' or photo.user.username == request.user.username: public_photos.append(photo) return render(request, 'imager_images/photos.html', {"photos": public_photos}) + + +def single_album(request, album_id): + """Render a specific album.""" + album = Album.objects.get(id=album_id) + if album.published != 'private' or album.user.username == request.user.username: + return render( + request, + 'imager_images/album.html', + {'album': album} + ) + return HttpResponse('Unauthorized', status=401) + + +def all_albums(request): + """Render all public albums.""" + public_albums = [] + albums = Album.objects.all() + for album in albums: + if album.published != 'private' or album.user.username == request.user.username: + public_albums.append(album) + return render( + request, + 'imager_images/albums.html', + {'albums': public_albums} + ) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index 0ad5b68..7f6d8e0 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -24,7 +24,6 @@ class ProfileTestCase(TestCase): def setUp(self): """The appropriate setup for the appropriate test.""" - self.foo = "bar" self.users = [UserFactory.create() for i in range(20)] def test_profile_is_made_when_user_is_saved(self): diff --git a/imagersite/imagersite/templates/imagersite/album.html b/imagersite/imagersite/templates/imagersite/album.html new file mode 100644 index 0000000..93ed697 --- /dev/null +++ b/imagersite/imagersite/templates/imagersite/album.html @@ -0,0 +1,4 @@ +{% extends 'imagersite/base.html' %} +{% block content %} +

      Album Page

      +{% endblock content %} \ No newline at end of file From 1e76e7ab6a9878bdb2293afb04eceede128a80bf Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 24 Jan 2017 10:45:17 -0800 Subject: [PATCH 49/74] made library view and url --- .../templates/imager_images/album.html | 2 +- .../templates/imager_images/albums.html | 16 ++++++++-------- .../templates/imager_images/library.html | 14 ++++++++++++++ imagersite/imager_images/urls.py | 7 ++++--- imagersite/imager_images/views.py | 11 +++++++++++ .../templates/imager_profile/library.html | 4 ---- imagersite/imagersite/settings.py | 4 +++- 7 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 imagersite/imager_images/templates/imager_images/library.html delete mode 100644 imagersite/imager_profile/templates/imager_profile/library.html diff --git a/imagersite/imager_images/templates/imager_images/album.html b/imagersite/imager_images/templates/imager_images/album.html index 0f7c28d..692a61c 100644 --- a/imagersite/imager_images/templates/imager_images/album.html +++ b/imagersite/imager_images/templates/imager_images/album.html @@ -3,7 +3,7 @@

      Your Album:

      -{% for photo in album.photos %} +{% for photo in album.photos.all %} {% endfor %}
      diff --git a/imagersite/imager_images/templates/imager_images/albums.html b/imagersite/imager_images/templates/imager_images/albums.html index cc73718..2454f54 100644 --- a/imagersite/imager_images/templates/imager_images/albums.html +++ b/imagersite/imager_images/templates/imager_images/albums.html @@ -1,15 +1,15 @@ {% extends 'imagersite/base.html' %} +{% load thumbnail %} {% block content %}

      Public Albums

      -
      +
      {% for album in albums %} - +

      {{ album.title }}

      + +{% thumbnail album.cover.image "200x200" crop="center" as im %} + +{% endthumbnail %} + {% endfor %}
      - {% endblock content %} \ No newline at end of file diff --git a/imagersite/imager_images/templates/imager_images/library.html b/imagersite/imager_images/templates/imager_images/library.html new file mode 100644 index 0000000..31aaab5 --- /dev/null +++ b/imagersite/imager_images/templates/imager_images/library.html @@ -0,0 +1,14 @@ +{% extends 'imagersite/base.html' %} +{% load thumbnail %} +{% block content %} +

      Library Page

      +
      + {% for album in albums %} + + {% thumbnail album.cover.image "200x200" crop="center" as im %} + + {% endthumbnail %} + + {% endfor %} +
      +{% endblock content %} \ No newline at end of file diff --git a/imagersite/imager_images/urls.py b/imagersite/imager_images/urls.py index d37541b..b7ffc34 100644 --- a/imagersite/imager_images/urls.py +++ b/imagersite/imager_images/urls.py @@ -1,10 +1,11 @@ """Images urls.""" from django.conf.urls import url -from .views import photo_view, all_photos, single_album, all_albums +from .views import photo_view, all_photos, single_album, all_albums, library urlpatterns = [ url(r'^photos/(?P\d+)', photo_view, name='public_profile'), url(r'^photos/$', all_photos, name='private_profile'), # display all of the public photos that have been uploaded - url(r'^albums/(?P[-\w]+)', single_album, name='single_album'), # display a single selected album - url(r'^albums/?', all_albums, name='all_albums') + url(r'^albums/(?P\d+)', single_album, name='single_album'), # display a single selected album + url(r'^albums/?', all_albums, name='all_albums'), + url(r'^library$', library, name='library'), ] diff --git a/imagersite/imager_images/views.py b/imagersite/imager_images/views.py index fa482c4..de6ccf0 100644 --- a/imagersite/imager_images/views.py +++ b/imagersite/imager_images/views.py @@ -2,6 +2,7 @@ from django.shortcuts import render from imager_images.models import Photo, Album from django.http import HttpResponse +from django.contrib.auth.decorators import login_required def photo_view(request, photo_id): @@ -46,3 +47,13 @@ def all_albums(request): 'imager_images/albums.html', {'albums': public_albums} ) + + +@login_required(login_url='/accounts/login/') +def library(request): + """Library view.""" + albums = request.user.albums.all() + photos = request.user.photos.all() + return render(request, + 'imager_images/library.html', + context={'albums': albums, 'photos': photos}) diff --git a/imagersite/imager_profile/templates/imager_profile/library.html b/imagersite/imager_profile/templates/imager_profile/library.html deleted file mode 100644 index 4ecc0ad..0000000 --- a/imagersite/imager_profile/templates/imager_profile/library.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends 'imagersite/base.html' %} -{% block content %} -

      Library Page

      -{% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index 7c00e4d..3383318 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -40,7 +40,8 @@ 'bootstrap3', 'imager_profile', 'imagersite', - 'imager_images' + 'imager_images', + 'sorl.thumbnail' ] MIDDLEWARE = [ @@ -140,3 +141,4 @@ LOGIN_REDIRECT_URL='/' MEDIA_ROOT = os.path.join(BASE_DIR, 'MEDIA') MEDIA_URL = "/media/" +THUMBNAIL_DEBUG = True From 4c930295a897874a1f700d174e46fadb691b2599 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 24 Jan 2017 11:29:45 -0800 Subject: [PATCH 50/74] fix albums template --- imagersite/imager_images/templates/imager_images/album.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagersite/imager_images/templates/imager_images/album.html b/imagersite/imager_images/templates/imager_images/album.html index 692a61c..77a69de 100644 --- a/imagersite/imager_images/templates/imager_images/album.html +++ b/imagersite/imager_images/templates/imager_images/album.html @@ -2,7 +2,7 @@ {% block content %}

      Your Album:

      - + {% for photo in album.photos.all %} {% endfor %} From f9f3a6f704f54c66c201d62a2ae26fb43f43fb7c Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Tue, 24 Jan 2017 11:32:35 -0800 Subject: [PATCH 51/74] update requirements.pip --- requirements.pip | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/requirements.pip b/requirements.pip index d432505..261e22a 100644 --- a/requirements.pip +++ b/requirements.pip @@ -4,6 +4,7 @@ django-bootstrap3==8.1.0 django-registration==2.2 factory-boy==2.8.1 Faker==0.7.7 +ipdb==0.10.1 ipython==5.1.0 ipython-genutils==0.1.0 olefile==0.44 @@ -14,9 +15,12 @@ pkg-resources==0.0.0 prompt-toolkit==1.0.9 psycopg2==2.6.2 ptyprocess==0.5.1 +pudb==2016.2 Pygments==2.1.3 python-dateutil==2.6.0 simplegeneric==0.8.1 six==1.10.0 +sorl-thumbnail==12.3 traitlets==4.3.1 +urwid==1.3.1 wcwidth==0.1.7 From 7d872be9f61df0285ba8ab9760f3f7b7f650535d Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 24 Jan 2017 18:06:04 -0800 Subject: [PATCH 52/74] all existing tests pass --- imagersite/imager_profile/tests.py | 32 +++++++------------ imagersite/imagersite/settings.py | 2 +- .../templates/registration/login.html | 2 +- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index 7f6d8e0..fa37ece 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -16,6 +16,7 @@ class Meta: username = factory.Sequence(lambda n: "The Chosen {}".format(n)) email = factory.LazyAttribute( lambda x: "{}@foo.com".format(x.username.replace(" ", "")) + ) @@ -49,7 +50,6 @@ def test_user_model_has_str(self): # def test_user_model_has_attributes(self): # """Test user attributes are present.""" - # pass def test_active_users_counted(self): """Test acttive user count meets expectations.""" @@ -92,32 +92,21 @@ def test_home_route_templates(self): def test_login_redirect_code(self): """Test built-in login route redirects properly.""" user_register = UserFactory.create() + user_register.is_active = True user_register.username = "username" - user_register.password = "potatoes" + user_register.set_password("potatoes") user_register.save() response = self.client.post("/login/", { "username": user_register.username, "password": "potatoes" }) - self.assertTrue(response.status_code == 302) - - def test_login_redirect_home(self): - """Test built-in login route redirects to home.""" - user_register = UserFactory.create() - user_register.username = "username2" - user_register.password = "potatoes2" - user_register.save() - response = self.client.post("/login/", { - "username": user_register.username, - "password": "potatoes" - }, follow=True) - self.assertTrue(response.redirect_chain[0][0] == '/') + self.assertRedirects(response, '/profile/') def test_register_user(self): """Test that tests can register users.""" self.assertTrue(User.objects.count() == 0) - self.client.post("/registration/register/", { + self.client.post("/accounts/register/", { "username": "Sir_Joseph", "email": "e@mail.com", "password1": "rutabega", @@ -127,7 +116,7 @@ def test_register_user(self): def test_new_user_inactive(self): """Test django-created user starts as inactive.""" - self.client.post("/registration/register/", { + self.client.post("/accounts/register/", { "username": "Sir_Joseph", "email": "e@mail.com", "password1": "rutabega", @@ -138,7 +127,7 @@ def test_new_user_inactive(self): def test_registration_redirect(self): """Test redirect on registration.""" - response = self.client.post("/registration/register/", { + response = self.client.post("/accounts/register/", { "username": "Sir_Joseph", "email": "e@mail.com", "password1": "rutabega", @@ -148,12 +137,13 @@ def test_registration_redirect(self): def test_registration_reidrect_home(self): """Test registration redirects home.""" - response = self.client.post("/registration/register/", { + response = self.client.post("/accounts/register/", { "username": "Sir_Joseph", "email": "e@mail.com", "password1": "rutabega", "password2": "rutabega" }, follow=True) - self.assertTrue( - response.redirect_chain[0][0] == "/registration/register/complete/" + self.assertRedirects( + response, + "/accounts/register/complete/" ) diff --git a/imagersite/imagersite/settings.py b/imagersite/imagersite/settings.py index 3383318..f34c300 100644 --- a/imagersite/imagersite/settings.py +++ b/imagersite/imagersite/settings.py @@ -138,7 +138,7 @@ EMAIL_PORT = 1025 # Login/out settings -LOGIN_REDIRECT_URL='/' +LOGIN_REDIRECT_URL='/profile/' MEDIA_ROOT = os.path.join(BASE_DIR, 'MEDIA') MEDIA_URL = "/media/" THUMBNAIL_DEBUG = True diff --git a/imagersite/imagersite/templates/registration/login.html b/imagersite/imagersite/templates/registration/login.html index e9c237a..8bf4b45 100644 --- a/imagersite/imagersite/templates/registration/login.html +++ b/imagersite/imagersite/templates/registration/login.html @@ -5,6 +5,6 @@ {% bootstrap_form form %} {% csrf_token %} {% bootstrap_button "Login" button_type="submit" button_class="btn-primary" %} - + {% endblock content %} \ No newline at end of file From b66727b869055595a4b08fd4099b2d710e5b518d Mon Sep 17 00:00:00 2001 From: pasaunders Date: Tue, 24 Jan 2017 23:27:41 -0800 Subject: [PATCH 53/74] working profile tests, first steps toward images tests. --- imagersite/imager_images/tests.py | 48 +++++++++++++++---- .../migrations/0006_auto_20170124_1837.py | 25 ++++++++++ .../migrations/0007_auto_20170124_1838.py | 20 ++++++++ imagersite/imager_profile/models.py | 4 +- imagersite/imager_profile/tests.py | 25 +++++++++- 5 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 imagersite/imager_profile/migrations/0006_auto_20170124_1837.py create mode 100644 imagersite/imager_profile/migrations/0007_auto_20170124_1838.py diff --git a/imagersite/imager_images/tests.py b/imagersite/imager_images/tests.py index 4f2bba7..667ffe6 100644 --- a/imagersite/imager_images/tests.py +++ b/imagersite/imager_images/tests.py @@ -1,9 +1,10 @@ +"""Test the imager_images app.""" from django.test import TestCase, Client, RequestFactory from django.contrib.auth.models import User +from django.db import models from imager_images.models import Photo, Album import factory - -# Create your tests here. +from faker import Faker class UserFactory(factory.django.DjangoModelFactory): @@ -14,7 +15,7 @@ class Meta: model = User - username = factory.Sequence(lambda n: "The Chosen {}".format(n)) + username = factory.Sequence(lambda n: "Prisoner number {}".format(n)) email = factory.LazyAttribute( lambda x: "{}@foo.com".format(x.username.replace(" ", "")) ) @@ -24,8 +25,23 @@ class PhotoTestCase(TestCase): """Photo model and view tests.""" def setUp(self): - """Set up users for photo tests.""" + """The appropriate setup for the appropriate test.""" self.users = [UserFactory.create() for i in range(20)] + for profile in Photo.objects.all(): + self.fake_photo_attrs(profile) + + def fake_photo_attrs(self, profile): + """Build a fake photo.""" + fake = Faker() + profile.image = # Work this one out + profile.title = fake.name() + profile.description = fake.paragraph() + profile.date_uploaded = models.DateTimeField(auto_now_add=True) + profile.date_modified = models.DateTimeField(auto_now=True) + profile.date_published = fake.date() + profile.published = fake.boolean() + profile.save() + """ To test: photo model is built @@ -39,8 +55,23 @@ class AlbumTestCase(TestCase): """Album model and view tests.""" def setUp(self): - """Set up users for photo tests.""" + """The appropriate setup for the appropriate test.""" self.users = [UserFactory.create() for i in range(20)] + for profile in Album.objects.all(): + self.fake_album_attrs(profile) + + def fake_profile_attrs(self, profile): + """Build a fake album.""" + fake = Faker() + profile.cover = + profile.title = + profile.description = + profile.photos = + profile.date_created = models.DateTimeField(auto_now_add=True) + profile.date_modified = models.DateTimeField(auto_now=True) + profile.date_published = fake.date() + profile.published = fake.boolean() + profile.save() """ To test: @@ -56,8 +87,9 @@ class FrontEndTestCase(TestCase): """Front end tests.""" def setUp(self): - """Set up users for front end tests.""" - self.users = [UserFactory.create() for i in range(20)] + """Set up client and requestfactory.""" + self.client = Client() + self.request = RequestFactory() """ To test: @@ -66,4 +98,4 @@ def setUp(self): all four templates are used albums are visible in albums.html correct number of photos and albums are visible - """ \ No newline at end of file + """ diff --git a/imagersite/imager_profile/migrations/0006_auto_20170124_1837.py b/imagersite/imager_profile/migrations/0006_auto_20170124_1837.py new file mode 100644 index 0000000..ad6d0dd --- /dev/null +++ b/imagersite/imager_profile/migrations/0006_auto_20170124_1837.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-25 02:37 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('imager_profile', '0005_auto_20170121_1732'), + ] + + operations = [ + migrations.AlterField( + model_name='imagerprofile', + name='address', + field=models.CharField(blank=True, max_length=70, null=True), + ), + migrations.AlterField( + model_name='imagerprofile', + name='phone_number', + field=models.CharField(blank=True, max_length=17, null=True), + ), + ] diff --git a/imagersite/imager_profile/migrations/0007_auto_20170124_1838.py b/imagersite/imager_profile/migrations/0007_auto_20170124_1838.py new file mode 100644 index 0000000..38e5473 --- /dev/null +++ b/imagersite/imager_profile/migrations/0007_auto_20170124_1838.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-01-25 02:38 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('imager_profile', '0006_auto_20170124_1837'), + ] + + operations = [ + migrations.AlterField( + model_name='imagerprofile', + name='phone_number', + field=models.CharField(blank=True, max_length=20, null=True), + ), + ] diff --git a/imagersite/imager_profile/models.py b/imagersite/imager_profile/models.py index 3256581..83a9467 100644 --- a/imagersite/imager_profile/models.py +++ b/imagersite/imager_profile/models.py @@ -41,12 +41,12 @@ class ImagerProfile(models.Model): null=True, blank=True ) - address = models.CharField(max_length=40, null=True, blank=True) + address = models.CharField(max_length=70, null=True, blank=True) bio = models.TextField(default="") personal_website = models.URLField(default="") for_hire = models.BooleanField(default=False) travel_distance = models.IntegerField(null=True, blank=True) - phone_number = models.CharField(max_length=15, null=True, blank=True) + phone_number = models.CharField(max_length=20, null=True, blank=True) STYLE_CHOICES = [ ('Portrait', 'Portrait'), ('Landscape', 'Landscape'), diff --git a/imagersite/imager_profile/tests.py b/imagersite/imager_profile/tests.py index fa37ece..f6d3a29 100644 --- a/imagersite/imager_profile/tests.py +++ b/imagersite/imager_profile/tests.py @@ -3,6 +3,7 @@ from django.contrib.auth.models import User from imager_profile.models import ImagerProfile import factory +from faker import Faker class UserFactory(factory.django.DjangoModelFactory): @@ -13,7 +14,7 @@ class Meta: model = User - username = factory.Sequence(lambda n: "The Chosen {}".format(n)) + username = factory.Sequence(lambda n: "Prisoner number {}".format(n)) email = factory.LazyAttribute( lambda x: "{}@foo.com".format(x.username.replace(" ", "")) @@ -26,6 +27,20 @@ class ProfileTestCase(TestCase): def setUp(self): """The appropriate setup for the appropriate test.""" self.users = [UserFactory.create() for i in range(20)] + for profile in ImagerProfile.objects.all(): + self.fake_profile_attrs(profile) + + def fake_profile_attrs(self, profile): + """Build a fake user.""" + fake = Faker() + profile.address = fake.street_name() + profile.bio = fake.paragraph() + profile.personal_website = fake.url() + profile.for_hire = fake.boolean() + profile.travel_distance = fake.random_int() + profile.phone_number = fake.phone_number() + profile.photography_type = 'Nikon' + profile.save() def test_profile_is_made_when_user_is_saved(self): """Test profile is made when user is saved.""" @@ -48,8 +63,14 @@ def test_user_model_has_str(self): user = self.users[0] self.assertIsInstance(str(user), str) - # def test_user_model_has_attributes(self): + def test_user_model_has_attributes(self): + """Test user attributes are present.""" + user = User.objects.get(pk=self.users[0].id) + self.assertTrue(user.profile.bio) + + # def test_user_model_has_attributes(self): add more of these! # """Test user attributes are present.""" + # user = User.objects.get(pk=self.users[0].id) def test_active_users_counted(self): """Test acttive user count meets expectations.""" From c7e4cd3359cefb7ff6527b64ee5fa396a019ef62 Mon Sep 17 00:00:00 2001 From: Amos Boldor Date: Wed, 25 Jan 2017 15:13:14 -0800 Subject: [PATCH 54/74] add photos stuff to library template --- .../templates/imager_images/library.html | 24 +++++++++++++------ .../imagersite/templates/imagersite/base.html | 1 + 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/imagersite/imager_images/templates/imager_images/library.html b/imagersite/imager_images/templates/imager_images/library.html index 31aaab5..d4d25cd 100644 --- a/imagersite/imager_images/templates/imager_images/library.html +++ b/imagersite/imager_images/templates/imager_images/library.html @@ -1,14 +1,24 @@ {% extends 'imagersite/base.html' %} {% load thumbnail %} {% block content %} -

      Library Page

      - {% for album in albums %} - - {% thumbnail album.cover.image "200x200" crop="center" as im %} +

      {{user.username}}'s Image Library

      +

      Albums:

      +{% for album in albums %} +
      +{% thumbnail album.cover.image "200x200" crop="center" as im %} + +{% endthumbnail %} + +{% endfor %} +

      Images

      +{% for photo in photos %} + +{% thumbnail photo.image "200x200" crop="center" as im %} - {% endthumbnail %} - - {% endfor %} +{% endthumbnail %} + +{{photo.title}} +{% endfor %}
      {% endblock content %} \ No newline at end of file diff --git a/imagersite/imagersite/templates/imagersite/base.html b/imagersite/imagersite/templates/imagersite/base.html index 8d0805d..38aebbf 100644 --- a/imagersite/imagersite/templates/imagersite/base.html +++ b/imagersite/imagersite/templates/imagersite/base.html @@ -17,6 +17,7 @@