changeset 1028:5ba2508939f7

Django 1.8 changes; first batch.
author Brian Neal <bgneal@gmail.com>
date Tue, 15 Dec 2015 21:01:07 -0600
parents cd4db27c90e3
children d9610b1e2a3d
files accounts/urls.py antispam/urls.py bandmap/urls.py bio/urls.py comments/migrations/0001_initial.py comments/migrations/0002_auto_20151214_1952.py comments/migrations/__init__.py comments/models.py comments/urls.py contact/urls.py contests/models.py contests/urls.py core/urls.py donations/urls.py downloads/migrations/0001_initial.py downloads/migrations/0002_auto_20151214_1958.py downloads/migrations/__init__.py downloads/models.py downloads/urls.py forums/migrations/0001_initial.py forums/migrations/0002_auto_20151214_2000.py forums/migrations/__init__.py forums/models.py forums/urls.py gcalendar/admin.py gcalendar/calendar.py gcalendar/urls.py irc/urls.py membermap/urls.py messages/urls.py news/urls.py news/views.py oembed/urls.py podcast/urls.py polls/urls.py potd/urls.py requirements.txt requirements_dev.txt sg101/settings/base.py sg101/settings/local.py sg101/settings/production.py sg101/urls.py shoutbox/urls.py smiley/urls.py user_photos/urls.py weblinks/urls.py ygroup/urls.py
diffstat 44 files changed, 780 insertions(+), 365 deletions(-) [+]
line wrap: on
line diff
--- a/accounts/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/accounts/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,58 +1,60 @@
 """urls for the accounts application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.conf import settings
+import django.contrib.auth.views as auth_views
 from django.views.generic import TemplateView
 
-urlpatterns = patterns('accounts.views',
-    url(r'^register/$', 'register', name='accounts-register'),
-    url(r'^register/1/$', 'register1', name='accounts-register1'),
-    url(r'^register/2/$', 'register2', name='accounts-register2'),
-    url(r'^register/code/$', 'get_code', name='accounts-code'),
-    url(r'^register/thanks/$', 'register_thanks', name='accounts-register_thanks'),
+import accounts.views
+
+urlpatterns = [
+    url(r'^register/$', accounts.views.register, name='accounts-register'),
+    url(r'^register/1/$', accounts.views.register1, name='accounts-register1'),
+    url(r'^register/2/$', accounts.views.register2, name='accounts-register2'),
+    url(r'^register/code/$', accounts.views.get_code, name='accounts-code'),
+    url(r'^register/thanks/$', accounts.views.register_thanks, name='accounts-register_thanks'),
     url(r'^register/confirm/(?P<username>[\w.@+-]{1,30})/(?P<key>[a-zA-Z0-9]{20})/$',
-        'register_confirm',
+        accounts.views.register_confirm,
         name='accounts-register_confirm'),
-)
+]
 
-urlpatterns += patterns('',
+urlpatterns += [
     url(r'^login/$',
-        'django.contrib.auth.views.login',
+        auth_views.login,
         kwargs={'template_name': 'accounts/login.html'},
         name='accounts-login'),
     url(r'^logout/$',
-        'django.contrib.auth.views.logout',
+        auth_views.logout,
         kwargs={'template_name': 'accounts/logout.html'},
         name='accounts-logout'),
-    (r'^password/$',
-        'django.contrib.auth.views.password_change',
+    url(r'^password/$',
+        auth_views.password_change,
         {'template_name': 'accounts/password_change.html',
          'post_change_redirect': settings.LOGIN_REDIRECT_URL}),
     url(r'^password/reset/$',
-        'django.contrib.auth.views.password_reset',
+        auth_views.password_reset,
         kwargs={'template_name': 'accounts/password_reset.html',
          'email_template_name': 'accounts/password_reset_email.txt',
          'post_reset_redirect': '/accounts/password/reset/sent/'},
         name='accounts-password_reset'),
     url(r'^password/reset/sent/$',
-        'django.contrib.auth.views.password_reset_done',
+        auth_views.password_reset_done,
         kwargs={'template_name': 'accounts/password_reset_sent.html'},
         name='accounts-password_reset_sent'),
     url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9a-z]+-\w+)/$',
-        'django.contrib.auth.views.password_reset_confirm',
+        auth_views.password_reset_confirm,
         kwargs={
             'template_name': 'accounts/password_reset_confirm.html',
             'post_reset_redirect': '/accounts/password/reset/success/',
             },
         name='accounts-password_reset_confirm'),
     url(r'^password/reset/success/$',
-        'django.contrib.auth.views.password_reset_complete',
+        auth_views.password_reset_complete,
         kwargs={'template_name': 'accounts/password_reset_complete.html'},
         name='accounts-password_reset_success'),
     url(r'^username/query/$',
-        'accounts.views.username_query',
+        accounts.views.username_query,
         name='accounts-username_query'),
     url(r'^username/sent/$',
         TemplateView.as_view(template_name='accounts/username_sent.html'),
         name='accounts-username_sent'),
-)
-
+]
--- a/antispam/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/antispam/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,6 +1,9 @@
 """URLs for the antispam application."""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('antispam.views',
-    url(r'^suspended/$', 'suspended', name='antispam-suspended'),
-)
+import antispam.views
+
+
+urlpatterns = [
+    url(r'^suspended/$', antispam.views.suspended, name='antispam-suspended'),
+]
--- a/bandmap/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/bandmap/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,14 +1,16 @@
 """urls for the bandmap application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('',
+import bandmap.views
+
+urlpatterns = [
     url(r'^$',
-        'bandmap.views.map_view',
+        bandmap.views.map_view,
         name='bandmap-map'),
     url(r'^add/$',
-        'bandmap.views.add_band',
+        bandmap.views.add_band,
         name='bandmap-add'),
     url(r'^query/$',
-        'bandmap.views.query',
+        bandmap.views.query,
         name='bandmap-query'),
-)
+]
--- a/bio/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/bio/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,15 +1,17 @@
 """urls for the bio application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('bio.views',
+import bio.views
+
+urlpatterns = [
     url(r'^members/(?P<type>user|date)/$',
-        'member_list',
+        bio.views.member_list,
         name='bio-member_list'),
-    url(r'^members/search/$', 'member_search', name='bio-member_search'),
-    url(r'^me/$', 'my_profile', name='bio-me'),
-    url(r'^view/(?P<username>[\w.@+-]{1,30})/$', 'view_profile', name='bio-view_profile'),
-    url(r'^edit/$', 'edit_profile', name='bio-edit_profile'),
-    url(r'^edit/elsewhere/$', 'edit_elsewhere', name='bio-edit_elsewhere'),
-    url(r'^avatar/$', 'change_avatar', name='bio-change_avatar'),
-    url(r'^flag/(\d+)/$', 'flag_profile', name='bio-flag_profile'),
-)
+    url(r'^members/search/$', bio.views.member_search, name='bio-member_search'),
+    url(r'^me/$', bio.views.my_profile, name='bio-me'),
+    url(r'^view/(?P<username>[\w.@+-]{1,30})/$', bio.views.view_profile, name='bio-view_profile'),
+    url(r'^edit/$', bio.views.edit_profile, name='bio-edit_profile'),
+    url(r'^edit/elsewhere/$', bio.views.edit_elsewhere, name='bio-edit_elsewhere'),
+    url(r'^avatar/$', bio.views.change_avatar, name='bio-change_avatar'),
+    url(r'^flag/(\d+)/$', bio.views.flag_profile, name='bio-flag_profile'),
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/comments/migrations/0001_initial.py	Tue Dec 15 21:01:07 2015 -0600
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Comment',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('object_id', models.PositiveIntegerField(db_index=True)),
+                ('comment', models.TextField(max_length=3000)),
+                ('html', models.TextField(blank=True)),
+                ('creation_date', models.DateTimeField()),
+                ('ip_address', models.IPAddressField(verbose_name=b'IP Address')),
+                ('is_public', models.BooleanField(default=True, help_text=b'Uncheck this field to make the comment invisible.')),
+                ('is_removed', models.BooleanField(default=False, help_text=b'Check this field to replace the comment with a "This comment has been removed" message')),
+                ('content_type', models.ForeignKey(to='contenttypes.ContentType')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('creation_date',),
+            },
+        ),
+        migrations.CreateModel(
+            name='CommentFlag',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('flag_date', models.DateTimeField(auto_now_add=True)),
+                ('comment', models.ForeignKey(to='comments.Comment')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('flag_date',),
+            },
+        ),
+    ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/comments/migrations/0002_auto_20151214_1952.py	Tue Dec 15 21:01:07 2015 -0600
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('comments', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='comment',
+            name='ip_address',
+            field=models.GenericIPAddressField(verbose_name=b'IP Address'),
+        ),
+    ]
--- a/comments/models.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/comments/models.py	Tue Dec 15 21:01:07 2015 -0600
@@ -6,7 +6,7 @@
 from django.db import models
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
-from django.contrib.contenttypes import generic
+from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.auth.models import User
 from django.core import urlresolvers
 
@@ -32,12 +32,12 @@
     """My own version of a Comment class that can attach comments to any other model."""
     content_type = models.ForeignKey(ContentType)
     object_id = models.PositiveIntegerField(db_index=True)
-    content_object = generic.GenericForeignKey('content_type', 'object_id')
+    content_object = GenericForeignKey('content_type', 'object_id')
     user = models.ForeignKey(User)
     comment = models.TextField(max_length=COMMENT_MAX_LENGTH)
     html = models.TextField(blank=True)
     creation_date = models.DateTimeField()
-    ip_address = models.IPAddressField('IP Address')
+    ip_address = models.GenericIPAddressField('IP Address')
     is_public = models.BooleanField(default=True,
             help_text='Uncheck this field to make the comment invisible.')
     is_removed = models.BooleanField(default=False,
--- a/comments/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/comments/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,16 +1,16 @@
 """
 URLs for the comments application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
+import django.contrib.contenttypes.views
 
-urlpatterns = patterns('comments.views',
-    url(r'^flag/$', 'flag_comment', name='comments-flag'),
-    url(r'^markdown/$', 'markdown_preview', name='comments-markdown_preview'),
-    url(r'^post/$', 'post_comment', name='comments-post'),
-)
+import comments.views
 
-urlpatterns += patterns('',
+urlpatterns = [
+    url(r'^flag/$', comments.views.flag_comment, name='comments-flag'),
+    url(r'^markdown/$', comments.views.markdown_preview, name='comments-markdown_preview'),
+    url(r'^post/$', comments.views.post_comment, name='comments-post'),
     url(r'^cr/(\d+)/(\d+)/$',
-        'django.contrib.contenttypes.views.shortcut',
+        django.contrib.contenttypes.views.shortcut,
         name='comments-url-redirect'),
-)
+]
--- a/contact/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/contact/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,10 +1,12 @@
 """urls for the contact application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.generic import TemplateView
 
-urlpatterns = patterns('',
-   url(r'^$', 'contact.views.contact_form', name='contact-form'),
+import contact.views
+
+urlpatterns = [
+   url(r'^$', contact.views.contact_form, name='contact-form'),
    url(r'^thanks/$',
        TemplateView.as_view(template_name='contact/contact_thanks.html'),
        name='contact-thanks'),
-)
+]
--- a/contests/models.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/contests/models.py	Tue Dec 15 21:01:07 2015 -0600
@@ -34,8 +34,8 @@
     creation_date = models.DateTimeField(blank=True)
     end_date = models.DateTimeField()
     contestants = models.ManyToManyField(User, related_name='contests',
-            null=True, blank=True)
-    winners = models.ManyToManyField(User, null=True, blank=True,
+            blank=True)
+    winners = models.ManyToManyField(User, blank=True,
             related_name='winning_contests')
     win_date = models.DateTimeField(null=True, blank=True)
     meta_description = models.TextField()
--- a/contests/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/contests/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -2,13 +2,14 @@
 Url patterns for the contests application.
 
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.generic import DetailView, ListView
 
 from contests.models import Contest
+import contests.views
 
 
-urlpatterns = patterns('',
+urlpatterns = [
    url(r'^$',
        ListView.as_view(
            context_object_name='contests',
@@ -16,7 +17,7 @@
        name='contests-index'),
 
    url(r'^enter/$',
-       'contests.views.enter',
+       contests.views.enter,
        name='contests-enter'),
 
    url(r'^c/(?P<slug>[\w-]+)/$',
@@ -24,4 +25,4 @@
            context_object_name='contest',
            queryset=Contest.public_objects.all().prefetch_related('winners')),
        name='contests-contest'),
-)
+]
--- a/core/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/core/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,9 +1,12 @@
 """
 Urls for the core application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('core.views',
-    url(r'^markdown_help/$', 'markdown_help', name='core-markdown_help'),
-    url(r'^ajax/users/$', 'ajax_users', name='core-ajax_users'),
-)
+import core.views
+
+
+urlpatterns = [
+    url(r'^markdown_help/$', core.views.markdown_help, name='core-markdown_help'),
+    url(r'^ajax/users/$', core.views.ajax_users, name='core-ajax_users'),
+]
--- a/donations/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/donations/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,14 +1,15 @@
 """
 URLs for the donations application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.generic import TemplateView
 
-urlpatterns = patterns('donations.views',
-    url(r'^$', 'index', name='donations-index'),
-    url(r'^ipn/$', 'ipn', name='donations-ipn'),
-)
-urlpatterns += patterns('',
+import donations.views
+
+
+urlpatterns = [
+    url(r'^$', donations.views.index, name='donations-index'),
+    url(r'^ipn/$', donations.views.ipn, name='donations-ipn'),
     url(r'^thanks/$', TemplateView.as_view(template_name='donations/thanks.html'),
         name='donations-thanks'),
-)
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/downloads/migrations/0001_initial.py	Tue Dec 15 21:01:07 2015 -0600
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import downloads.models
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='AllowedExtension',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('extension', models.CharField(help_text=b'e.g. .txt', max_length=8)),
+            ],
+            options={
+                'ordering': ('extension',),
+            },
+        ),
+        migrations.CreateModel(
+            name='Category',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('title', models.CharField(max_length=64)),
+                ('slug', models.SlugField(max_length=64)),
+                ('description', models.TextField(blank=True)),
+                ('count', models.IntegerField(default=0, blank=True)),
+            ],
+            options={
+                'ordering': ('title',),
+                'verbose_name_plural': 'Categories',
+            },
+        ),
+        migrations.CreateModel(
+            name='Download',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('title', models.CharField(max_length=128)),
+                ('description', models.TextField()),
+                ('html', models.TextField(blank=True)),
+                ('file', models.FileField(upload_to=downloads.models.download_path)),
+                ('date_added', models.DateTimeField(db_index=True)),
+                ('ip_address', models.IPAddressField(verbose_name=b'IP Address')),
+                ('update_date', models.DateTimeField(db_index=True, blank=True)),
+                ('hits', models.IntegerField(default=0)),
+                ('average_score', models.FloatField(default=0.0)),
+                ('total_votes', models.IntegerField(default=0)),
+                ('is_public', models.BooleanField(default=False, db_index=True)),
+                ('category', models.ForeignKey(to='downloads.Category')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='PendingDownload',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('title', models.CharField(max_length=128)),
+                ('description', models.TextField()),
+                ('html', models.TextField(blank=True)),
+                ('file', models.FileField(upload_to=downloads.models.download_path)),
+                ('date_added', models.DateTimeField(db_index=True)),
+                ('ip_address', models.IPAddressField(verbose_name=b'IP Address')),
+                ('update_date', models.DateTimeField(db_index=True, blank=True)),
+                ('category', models.ForeignKey(to='downloads.Category')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('date_added',),
+            },
+        ),
+        migrations.CreateModel(
+            name='VoteRecord',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('vote_date', models.DateTimeField(auto_now_add=True)),
+                ('download', models.ForeignKey(to='downloads.Download')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('-vote_date',),
+            },
+        ),
+    ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/downloads/migrations/0002_auto_20151214_1958.py	Tue Dec 15 21:01:07 2015 -0600
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('downloads', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='download',
+            name='ip_address',
+            field=models.GenericIPAddressField(verbose_name=b'IP Address'),
+        ),
+        migrations.AlterField(
+            model_name='pendingdownload',
+            name='ip_address',
+            field=models.GenericIPAddressField(verbose_name=b'IP Address'),
+        ),
+    ]
--- a/downloads/models.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/downloads/models.py	Tue Dec 15 21:01:07 2015 -0600
@@ -57,7 +57,7 @@
     file = models.FileField(upload_to=download_path)
     user = models.ForeignKey(User)
     date_added = models.DateTimeField(db_index=True)
-    ip_address = models.IPAddressField('IP Address')
+    ip_address = models.GenericIPAddressField('IP Address')
     update_date = models.DateTimeField(db_index=True, blank=True)
 
     class Meta:
--- a/downloads/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/downloads/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,19 +1,21 @@
 """
 URLs for the downloads application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('downloads.views',
-    url(r'^$', 'index', name='downloads-index'),
-    url(r'^add/$', 'add', name='downloads-add'),
+import downloads.views
+
+urlpatterns = [
+    url(r'^$', downloads.views.index, name='downloads-index'),
+    url(r'^add/$', downloads.views.add, name='downloads-add'),
     url(r'^category/(?P<slug>[\w\d-]+)/(?P<sort>title|date|rating|hits)/$',
-       'category',
+       downloads.views.category,
        name='downloads-category'),
-    url(r'^details/(\d+)/$', 'details', name='downloads-details'),
-    url(r'^new/$', 'new', name='downloads-new'),
-    url(r'^popular/$', 'popular', name='downloads-popular'),
-    url(r'^request/$', 'request_download', name='downloads-request_download'),
-    url(r'^rate/$', 'rate_download', name='downloads-rate'),
-    url(r'^rating/$', 'rating', name='downloads-rating'),
-    url(r'^thanks/$', 'thanks', name='downloads-add_thanks'),
-)
+    url(r'^details/(\d+)/$', downloads.views.details, name='downloads-details'),
+    url(r'^new/$', downloads.views.new, name='downloads-new'),
+    url(r'^popular/$', downloads.views.popular, name='downloads-popular'),
+    url(r'^request/$', downloads.views.request_download, name='downloads-request_download'),
+    url(r'^rate/$', downloads.views.rate_download, name='downloads-rate'),
+    url(r'^rating/$', downloads.views.rating, name='downloads-rating'),
+    url(r'^thanks/$', downloads.views.thanks, name='downloads-add_thanks'),
+]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/forums/migrations/0001_initial.py	Tue Dec 15 21:01:07 2015 -0600
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('oembed', '__first__'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('auth', '0006_require_contenttypes_0002'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Attachment',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('order', models.IntegerField()),
+                ('embed', models.ForeignKey(to='oembed.Oembed')),
+            ],
+            options={
+                'ordering': ('order',),
+            },
+        ),
+        migrations.CreateModel(
+            name='Category',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('name', models.CharField(max_length=80)),
+                ('slug', models.SlugField(max_length=80)),
+                ('position', models.IntegerField(default=0, blank=True)),
+                ('groups', models.ManyToManyField(help_text=b'If groups are assigned to this category, only members of those groups can view this category.', to='auth.Group', null=True, blank=True)),
+            ],
+            options={
+                'ordering': ('position',),
+                'verbose_name_plural': 'Categories',
+            },
+        ),
+        migrations.CreateModel(
+            name='FlaggedPost',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('flag_date', models.DateTimeField(auto_now_add=True)),
+            ],
+            options={
+                'ordering': ('flag_date',),
+            },
+        ),
+        migrations.CreateModel(
+            name='Forum',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('name', models.CharField(max_length=80)),
+                ('slug', models.SlugField(max_length=80)),
+                ('description', models.TextField(default=b'', blank=True)),
+                ('position', models.IntegerField(default=0, blank=True)),
+                ('topic_count', models.IntegerField(default=0, blank=True)),
+                ('post_count', models.IntegerField(default=0, blank=True)),
+                ('category', models.ForeignKey(related_name='forums', to='forums.Category')),
+            ],
+            options={
+                'ordering': ('position',),
+            },
+        ),
+        migrations.CreateModel(
+            name='ForumLastVisit',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('begin_date', models.DateTimeField()),
+                ('end_date', models.DateTimeField()),
+                ('forum', models.ForeignKey(to='forums.Forum')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('-end_date',),
+            },
+        ),
+        migrations.CreateModel(
+            name='Post',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('creation_date', models.DateTimeField(db_index=True)),
+                ('update_date', models.DateTimeField(db_index=True)),
+                ('body', models.TextField()),
+                ('html', models.TextField()),
+                ('user_ip', models.IPAddressField(default=b'', null=True, blank=True)),
+                ('attachments', models.ManyToManyField(to='oembed.Oembed', through='forums.Attachment')),
+            ],
+            options={
+                'ordering': ('creation_date',),
+                'get_latest_by': 'creation_date',
+                'verbose_name': 'forum post',
+                'verbose_name_plural': 'forum posts',
+            },
+        ),
+        migrations.CreateModel(
+            name='Topic',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('name', models.CharField(max_length=255)),
+                ('creation_date', models.DateTimeField(db_index=True)),
+                ('view_count', models.IntegerField(default=0, blank=True)),
+                ('sticky', models.BooleanField(default=False)),
+                ('locked', models.BooleanField(default=False)),
+                ('post_count', models.IntegerField(default=0, blank=True)),
+                ('update_date', models.DateTimeField(db_index=True)),
+                ('bookmarkers', models.ManyToManyField(related_name='favorite_topics', verbose_name=b'bookmarkers', to=settings.AUTH_USER_MODEL, blank=True)),
+                ('forum', models.ForeignKey(related_name='topics', to='forums.Forum')),
+                ('last_post', models.OneToOneField(related_name='parent_topic', null=True, blank=True, to='forums.Post')),
+                ('subscribers', models.ManyToManyField(related_name='subscriptions', verbose_name=b'subscribers', to=settings.AUTH_USER_MODEL, blank=True)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('-sticky', '-update_date'),
+            },
+        ),
+        migrations.CreateModel(
+            name='TopicLastVisit',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('last_visit', models.DateTimeField(db_index=True)),
+                ('topic', models.ForeignKey(to='forums.Topic')),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ('-last_visit',),
+            },
+        ),
+        migrations.AddField(
+            model_name='post',
+            name='topic',
+            field=models.ForeignKey(related_name='posts', to='forums.Topic'),
+        ),
+        migrations.AddField(
+            model_name='post',
+            name='user',
+            field=models.ForeignKey(related_name='posts', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='forum',
+            name='last_post',
+            field=models.OneToOneField(related_name='parent_forum', null=True, blank=True, to='forums.Post'),
+        ),
+        migrations.AddField(
+            model_name='forum',
+            name='moderators',
+            field=models.ManyToManyField(to='auth.Group', null=True, blank=True),
+        ),
+        migrations.AddField(
+            model_name='flaggedpost',
+            name='post',
+            field=models.ForeignKey(to='forums.Post'),
+        ),
+        migrations.AddField(
+            model_name='flaggedpost',
+            name='user',
+            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='attachment',
+            name='post',
+            field=models.ForeignKey(to='forums.Post'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='topiclastvisit',
+            unique_together=set([('user', 'topic')]),
+        ),
+        migrations.AlterUniqueTogether(
+            name='forumlastvisit',
+            unique_together=set([('user', 'forum')]),
+        ),
+    ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/forums/migrations/0002_auto_20151214_2000.py	Tue Dec 15 21:01:07 2015 -0600
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('forums', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='category',
+            name='groups',
+            field=models.ManyToManyField(help_text=b'If groups are assigned to this category, only members of those groups can view this category.', to='auth.Group', blank=True),
+        ),
+        migrations.AlterField(
+            model_name='forum',
+            name='moderators',
+            field=models.ManyToManyField(to='auth.Group', blank=True),
+        ),
+        migrations.AlterField(
+            model_name='post',
+            name='user_ip',
+            field=models.GenericIPAddressField(default=b'', null=True, blank=True),
+        ),
+    ]
--- a/forums/models.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/forums/models.py	Tue Dec 15 21:01:07 2015 -0600
@@ -19,7 +19,7 @@
     name = models.CharField(max_length=80)
     slug = models.SlugField(max_length=80)
     position = models.IntegerField(blank=True, default=0)
-    groups = models.ManyToManyField(Group, blank=True, null=True,
+    groups = models.ManyToManyField(Group, blank=True,
         help_text="If groups are assigned to this category, only members" \
                     " of those groups can view this category.")
 
@@ -86,7 +86,7 @@
     slug = models.SlugField(max_length=80)
     description = models.TextField(blank=True, default='')
     position = models.IntegerField(blank=True, default=0)
-    moderators = models.ManyToManyField(Group, blank=True, null=True)
+    moderators = models.ManyToManyField(Group, blank=True)
 
     # denormalized fields to reduce database hits
     topic_count = models.IntegerField(blank=True, default=0)
@@ -284,7 +284,7 @@
     update_date = models.DateTimeField(db_index=True)
     body = models.TextField()
     html = models.TextField()
-    user_ip = models.IPAddressField(blank=True, default='', null=True)
+    user_ip = models.GenericIPAddressField(blank=True, default='', null=True)
     attachments = models.ManyToManyField(Oembed, through='Attachment')
 
     class Meta:
--- a/forums/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/forums/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,58 +1,57 @@
 """
 URLs for the forums application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('forums.views.main',
-    url(r'^$', 'index', name='forums-index'),
-    url(r'^catchup/$', 'catchup_all', name='forums-catchup_all'),
-    url(r'^new-topic-success/(?P<tid>\d+)$', 'new_topic_thanks', name='forums-new_topic_thanks'),
-    url(r'^topic/(?P<id>\d+)/$', 'topic_index', name='forums-topic_index'),
-    url(r'^topic/(?P<id>\d+)/unread/$', 'topic_unread', name='forums-topic_unread'),
-    url(r'^topic/(?P<id>\d+)/latest/$', 'topic_latest', name='forums-topic_latest'),
-    url(r'^topic/active/(\d+)/$', 'active_topics', name='forums-active_topics'),
-    url(r'^delete-post/$', 'delete_post', name='forums-delete_post'),
-    url(r'^edit/(?P<id>\d+)/$', 'edit_post', name='forums-edit_post'),
-    url(r'^flag-post/$', 'flag_post', name='forums-flag_post'),
-    url(r'^forum/(?P<slug>[\w\d-]+)/$', 'forum_index', name='forums-forum_index'),
-    url(r'^forum/(?P<slug>[\w\d-]+)/catchup/$', 'forum_catchup', name='forums-catchup'),
-    url(r'^forum/(?P<slug>[\w\d-]+)/new-topic/$', 'new_topic', name='forums-new_topic'),
-    url(r'^mod/forum/(?P<slug>[\w\d-]+)/$', 'mod_forum', name='forums-mod_forum'),
-    url(r'^mod/topic/delete/(\d+)/$', 'mod_topic_delete', name='forums-mod_topic_delete'),
-    url(r'^mod/topic/lock/(\d+)/$', 'mod_topic_lock', name='forums-mod_topic_lock'),
-    url(r'^mod/topic/move/(\d+)/$', 'mod_topic_move', name='forums-mod_topic_move'),
-    url(r'^mod/topic/split/(\d+)/$', 'mod_topic_split', name='forums-mod_topic_split'),
-    url(r'^mod/topic/stick/(\d+)/$', 'mod_topic_stick', name='forums-mod_topic_stick'),
-    url(r'^my-posts/$', 'my_posts', name='forums-my_posts'),
-    url(r'^post/(\d+)/$', 'goto_post', name='forums-goto_post'),
-    url(r'^post/ip/(\d+)/$', 'post_ip_info', name='forums-post_ip_info'),
-    url(r'^post/new/(?P<topic_id>\d+)/$', 'new_post', name='forums-new_post'),
-    url(r'^posts/(?P<username>[\w.@+-]{1,30})/$', 'posts_for_user', name='forums-posts_for_user'),
-    url(r'^quick-reply/$', 'quick_reply_ajax', name='forums-quick_reply'),
-    url(r'^unanswered/$', 'unanswered_topics', name='forums-unanswered_topics'),
-    url(r'^unread/$', 'unread_topics', name='forums-unread_topics'),
-)
+import forums.views.attachments as attachments
+import forums.views.favorites as favorites
+import forums.views.main as main
+import forums.views.spam as spam
+import forums.views.subscriptions as subscriptions
 
-urlpatterns += patterns('forums.views.favorites',
-    url(r'^favorite/(\d+)/$', 'favorite_topic', name='forums-favorite_topic'),
-    url(r'^favorites/$', 'manage_favorites', name='forums-manage_favorites'),
-    url(r'^favorites/(\d+)/$', 'favorites_status', name='forums-favorites_status'),
-    url(r'^unfavorite/(\d+)/$', 'unfavorite_topic', name='forums-unfavorite_topic'),
-)
 
-urlpatterns += patterns('forums.views.subscriptions',
-    url(r'^subscribe/(\d+)/$', 'subscribe_topic', name='forums-subscribe_topic'),
-    url(r'^subscriptions/$', 'manage_subscriptions', name='forums-manage_subscriptions'),
-    url(r'^subscriptions/(\d+)/$', 'subscription_status', name='forums-subscription_status'),
-    url(r'^unsubscribe/(\d+)/$', 'unsubscribe_topic', name='forums-unsubscribe_topic'),
-)
+urlpatterns = [
+    url(r'^$', main.index, name='forums-index'),
+    url(r'^catchup/$', main.catchup_all, name='forums-catchup_all'),
+    url(r'^new-topic-success/(?P<tid>\d+)$', main.new_topic_thanks, name='forums-new_topic_thanks'),
+    url(r'^topic/(?P<id>\d+)/$', main.topic_index, name='forums-topic_index'),
+    url(r'^topic/(?P<id>\d+)/unread/$', main.topic_unread, name='forums-topic_unread'),
+    url(r'^topic/(?P<id>\d+)/latest/$', main.topic_latest, name='forums-topic_latest'),
+    url(r'^topic/active/(\d+)/$', main.active_topics, name='forums-active_topics'),
+    url(r'^delete-post/$', main.delete_post, name='forums-delete_post'),
+    url(r'^edit/(?P<id>\d+)/$', main.edit_post, name='forums-edit_post'),
+    url(r'^flag-post/$', main.flag_post, name='forums-flag_post'),
+    url(r'^forum/(?P<slug>[\w\d-]+)/$', main.forum_index, name='forums-forum_index'),
+    url(r'^forum/(?P<slug>[\w\d-]+)/catchup/$', main.forum_catchup, name='forums-catchup'),
+    url(r'^forum/(?P<slug>[\w\d-]+)/new-topic/$', main.new_topic, name='forums-new_topic'),
+    url(r'^mod/forum/(?P<slug>[\w\d-]+)/$', main.mod_forum, name='forums-mod_forum'),
+    url(r'^mod/topic/delete/(\d+)/$', main.mod_topic_delete, name='forums-mod_topic_delete'),
+    url(r'^mod/topic/lock/(\d+)/$', main.mod_topic_lock, name='forums-mod_topic_lock'),
+    url(r'^mod/topic/move/(\d+)/$', main.mod_topic_move, name='forums-mod_topic_move'),
+    url(r'^mod/topic/split/(\d+)/$', main.mod_topic_split, name='forums-mod_topic_split'),
+    url(r'^mod/topic/stick/(\d+)/$', main.mod_topic_stick, name='forums-mod_topic_stick'),
+    url(r'^my-posts/$', main.my_posts, name='forums-my_posts'),
+    url(r'^post/(\d+)/$', main.goto_post, name='forums-goto_post'),
+    url(r'^post/ip/(\d+)/$', main.post_ip_info, name='forums-post_ip_info'),
+    url(r'^post/new/(?P<topic_id>\d+)/$', main.new_post, name='forums-new_post'),
+    url(r'^posts/(?P<username>[\w.@+-]{1,30})/$', main.posts_for_user, name='forums-posts_for_user'),
+    url(r'^quick-reply/$', main.quick_reply_ajax, name='forums-quick_reply'),
+    url(r'^unanswered/$', main.unanswered_topics, name='forums-unanswered_topics'),
+    url(r'^unread/$', main.unread_topics, name='forums-unread_topics'),
 
-urlpatterns += patterns('forums.views.spam',
-    url(r'^spammer/(\d+)/$', 'spammer', name='forums-spammer'),
-    url(r'^spammer/nailed/(\d+)/$', 'spammer_nailed', name='forums-spammer_nailed'),
-    url(r'^stranger/(\d+)/$', 'stranger', name='forums-stranger'),
-)
+    url(r'^favorite/(\d+)/$', favorites.favorite_topic, name='forums-favorite_topic'),
+    url(r'^favorites/$', favorites.manage_favorites, name='forums-manage_favorites'),
+    url(r'^favorites/(\d+)/$', favorites.favorites_status, name='forums-favorites_status'),
+    url(r'^unfavorite/(\d+)/$', favorites.unfavorite_topic, name='forums-unfavorite_topic'),
 
-urlpatterns += patterns('forums.views.attachments',
-    url(r'^fetch_attachments/$', 'fetch_attachments', name='forums-fetch_attachments'),
-)
+    url(r'^subscribe/(\d+)/$', subscriptions.subscribe_topic, name='forums-subscribe_topic'),
+    url(r'^subscriptions/$', subscriptions.manage_subscriptions, name='forums-manage_subscriptions'),
+    url(r'^subscriptions/(\d+)/$', subscriptions.subscription_status, name='forums-subscription_status'),
+    url(r'^unsubscribe/(\d+)/$', subscriptions.unsubscribe_topic, name='forums-unsubscribe_topic'),
+
+    url(r'^spammer/(\d+)/$', spam.spammer, name='forums-spammer'),
+    url(r'^spammer/nailed/(\d+)/$', spam.spammer_nailed, name='forums-spammer_nailed'),
+    url(r'^stranger/(\d+)/$', spam.stranger, name='forums-stranger'),
+
+    url(r'^fetch_attachments/$', attachments.fetch_attachments, name='forums-fetch_attachments'),
+]
--- a/gcalendar/admin.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/gcalendar/admin.py	Tue Dec 15 21:01:07 2015 -0600
@@ -3,7 +3,7 @@
 
 """
 from django.conf import settings
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.contrib import admin
 from django.contrib import messages
 from django.contrib.sites.models import Site
@@ -37,7 +37,7 @@
 
     def get_urls(self):
         urls = super(EventAdmin, self).get_urls()
-        my_urls = patterns('',
+        my_urls = [
             url(r'^google_sync/$',
                 self.admin_site.admin_view(self.google_sync),
                 name="gcalendar-google_sync"),
@@ -47,7 +47,7 @@
              url(r'^auth_return/$',
                 self.admin_site.admin_view(self.auth_return),
                 name="gcalendar-auth_return"),
-        )
+        ]
         return my_urls + urls
 
     def approve_events(self, request, qs):
--- a/gcalendar/calendar.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/gcalendar/calendar.py	Tue Dec 15 21:01:07 2015 -0600
@@ -9,7 +9,7 @@
 import httplib2
 from apiclient.discovery import build
 from apiclient.http import BatchHttpRequest
-from django.utils.tzinfo import FixedOffset
+from django.utils.timezone import get_fixed_timezone
 
 from gcalendar.models import Event
 
@@ -137,7 +137,7 @@
             except pytz.UnknownTimeZoneError:
                 raise CalendarError('Invalid time zone: %s' % tz_name)
             local = tz.localize(d)
-            zulu = local.astimezone(FixedOffset(0))
+            zulu = local.astimezone(get_fixed_timezone(0))
             s = zulu.strftime(self.DATE_TIME_TZ_FMT)
 
         return s
--- a/gcalendar/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/gcalendar/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,14 +1,17 @@
 """
 URLs for the gcalendar application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('gcalendar.views',
-    url(r'^$', 'index', name='gcalendar-index'),
-    url(r'^add/$', 'add_event', name='gcalendar-add'),
-    url(r'^change/$', 'edit_events', name='gcalendar-edit_events'),
-    url(r'^change/(\d+)/$', 'edit_event', name='gcalendar-edit_event'),
-    url(r'^delete/$', 'delete_event', name='gcalendar-delete'),
-    url(r'^thanks/add/$', 'add_thanks', name='gcalendar-add_thanks'),
-    url(r'^thanks/change/$', 'edit_thanks', name='gcalendar-edit_thanks'),
-)
+import gcalendar.views
+
+
+urlpatterns = [
+    url(r'^$', gcalendar.views.index, name='gcalendar-index'),
+    url(r'^add/$', gcalendar.views.add_event, name='gcalendar-add'),
+    url(r'^change/$', gcalendar.views.edit_events, name='gcalendar-edit_events'),
+    url(r'^change/(\d+)/$', gcalendar.views.edit_event, name='gcalendar-edit_event'),
+    url(r'^delete/$', gcalendar.views.delete_event, name='gcalendar-delete'),
+    url(r'^thanks/add/$', gcalendar.views.add_thanks, name='gcalendar-add_thanks'),
+    url(r'^thanks/change/$', gcalendar.views.edit_thanks, name='gcalendar-edit_thanks'),
+]
--- a/irc/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/irc/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,6 +1,9 @@
 """urls for the IRC application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('irc.views',
-   url(r'^$', 'view', name='irc-main'),
-)
+import irc.views
+
+
+urlpatterns = [
+   url(r'^$', irc.views.view, name='irc-main'),
+]
--- a/membermap/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/membermap/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,11 +1,13 @@
 """
 URLs for the member map application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('membermap.views',
-    url(r'^$', 'index', name='membermap-index'),
-    url(r'^add/$', 'add', name='membermap-add'),
-    url(r'^delete/$', 'delete', name='membermap-delete'),
-    url(r'^query/$', 'query', name='membermap-query'),
-)
+import membermap.views
+
+urlpatterns = [
+    url(r'^$', membermap.views.index, name='membermap-index'),
+    url(r'^add/$', membermap.views.add, name='membermap-add'),
+    url(r'^delete/$', membermap.views.delete, name='membermap-delete'),
+    url(r'^query/$', membermap.views.query, name='membermap-query'),
+]
--- a/messages/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/messages/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,36 +1,39 @@
 """urls for the Messages application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.generic.base import RedirectView
 
-urlpatterns = patterns('',
+import messages.views
+
+
+urlpatterns = [
     url(r'^$',
         RedirectView.as_view(permanent=True, url='/messages/inbox/'),
         name='messages-index'),
     url(r'^inbox/$',
-        'messages.views.inbox',
+        messages.views.inbox,
         name='messages-inbox'),
     url(r'^compose/$',
-        'messages.views.compose',
+        messages.views.compose,
         name='messages-compose'),
     url(r'^outbox/$',
-        'messages.views.outbox',
+        messages.views.outbox,
         name='messages-outbox'),
     url(r'^trash/$',
-        'messages.views.trash',
+        messages.views.trash,
         name='messages-trash'),
     url(r'^options/$',
-        'messages.views.options',
+        messages.views.options,
         name='messages-options'),
     url(r'^bulk/$',
-        'messages.views.bulk',
+        messages.views.bulk,
         name='messages-bulk'),
     url(r'^undelete/$',
-        'messages.views.undelete',
+        messages.views.undelete,
         name='messages-undelete'),
     url(r'^view/(\d+)/$',
-        'messages.views.view',
+        messages.views.view,
         name='messages-view'),
     url(r'^report/(\d+)/$',
-        'messages.views.report',
+        messages.views.report,
         name='messages-report'),
-)
+]
--- a/news/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/news/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,19 +1,22 @@
 """urls for the News application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('news.views',
-    url(r'^date/$', 'index', name='news-index_page'),
-    url(r'^archive/$', 'archive_index', name='news-archive_index'),
+import news.views
+
+
+urlpatterns = [
+    url(r'^date/$', news.views.index, name='news-index_page'),
+    url(r'^archive/$', news.views.archive_index, name='news-archive_index'),
     url(r'^archive/(?P<year>\d{4})/(?P<month>\d\d?)/$',
-        'archive',
+        news.views.archive,
         name='news-archive_page'),
-    url(r'^categories/$', 'category_index', name='news-category_index'),
-    url(r'^category/(?P<slug>[\w\d-]+)/$', 'category', name='news-category'),
-    url(r'^email/(\d+)/$', 'email_story', name='news-email_story'),
-    url(r'^email/thanks/$', 'email_thanks', name='news-email_thanks'),
-    url(r'^story/(\d+)/$', 'story', name='news-story'),
-    url(r'^submit/$', 'submit', name='news-submit'),
-    url(r'^submit/thanks/$', 'submit_thanks', name='news-submit_thanks'),
-    url(r'^tags/$', 'tags', name='news-tag_index'),
-    url(r'^tag/(?P<tag_name>[^/]+)/$', 'tag', name='news-tag_page'),
-)
+    url(r'^categories/$', news.views.category_index, name='news-category_index'),
+    url(r'^category/(?P<slug>[\w\d-]+)/$', news.views.category, name='news-category'),
+    url(r'^email/(\d+)/$', news.views.email_story, name='news-email_story'),
+    url(r'^email/thanks/$', news.views.email_thanks, name='news-email_thanks'),
+    url(r'^story/(\d+)/$', news.views.story, name='news-story'),
+    url(r'^submit/$', news.views.submit, name='news-submit'),
+    url(r'^submit/thanks/$', news.views.submit_thanks, name='news-submit_thanks'),
+    url(r'^tags/$', news.views.tags, name='news-tag_index'),
+    url(r'^tag/(?P<tag_name>[^/]+)/$', news.views.tag, name='news-tag_page'),
+]
--- a/news/views.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/news/views.py	Tue Dec 15 21:01:07 2015 -0600
@@ -4,12 +4,12 @@
 
 import datetime
 from django.conf import settings
-from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.template.loader import render_to_string
 from django.http import HttpResponseRedirect
 from django.contrib.auth.decorators import login_required
 from django.shortcuts import get_object_or_404
+from django.shortcuts import render
 from django.core.paginator import InvalidPage
 from django.core.urlresolvers import reverse
 from django.contrib.sites.models import Site
@@ -18,7 +18,6 @@
 from tagging.models import Tag
 from tagging.models import TaggedItem
 
-from core.html import clean_html
 from core.functions import send_mail
 from core.functions import get_full_name
 from core.functions import get_page
@@ -56,21 +55,19 @@
     # than one at a time in the template; this saves database queries
     attach_extra_attrs(the_page.object_list)
 
-    return render_to_response('news/index.html', {
+    return render(request, 'news/index.html', {
         'title': 'Main Index',
         'page': the_page,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
 def archive_index(request):
     dates = Story.objects.dates('date_submitted', 'month', order='DESC')
-    return render_to_response('news/archive_index.html', {
+    return render(request, 'news/archive_index.html', {
         'title': 'News Archive',
         'dates': dates,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
@@ -89,11 +86,10 @@
 
     month_name = datetime.date(int(year), int(month), 1).strftime('%B')
 
-    return render_to_response('news/index.html', {
+    return render(request, 'news/index.html', {
         'title': 'Archive for %s, %s' % (month_name, year),
         'page': the_page,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
@@ -103,10 +99,9 @@
     for cat in categories:
         cat_list.append((cat, cat.story_set.defer('tags')[:10]))
 
-    return render_to_response('news/category_index.html', {
+    return render(request, 'news/category_index.html', {
         'cat_list': cat_list,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
@@ -123,21 +118,19 @@
 
     attach_extra_attrs(the_page.object_list)
 
-    return render_to_response('news/index.html', {
+    return render(request, 'news/index.html', {
         'title': 'Category: ' + category.title,
         'page': the_page,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
 def story(request, story_id):
     story = get_object_or_404(Story.objects.select_related(
                 'submitter', 'category', 'forums_topic'), pk=story_id)
-    return render_to_response('news/story.html', {
+    return render(request, 'news/story.html', {
         'story': story,
-        },
-        context_instance=RequestContext(request))
+        })
 
 #######################################################################
 
@@ -151,27 +144,23 @@
     else:
         add_form = AddNewsForm()
 
-    return render_to_response('news/submit_news.html', {
+    return render(request, 'news/submit_news.html', {
         'add_form': add_form,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
 @login_required
 def submit_thanks(request):
-    return render_to_response('news/submit_news.html', {
-        },
-        context_instance = RequestContext(request))
+    return render(request, 'news/submit_news.html')
 
 #######################################################################
 
 def tags(request):
     tags = Tag.objects.cloud_for_model(Story)
-    return render_to_response('news/tag_index.html', {
+    return render(request, 'news/tag_index.html', {
         'tags': tags,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
@@ -189,11 +178,10 @@
 
     attach_extra_attrs(the_page.object_list)
 
-    return render_to_response('news/index.html', {
+    return render(request, 'news/index.html', {
         'title': 'Stories with tag: "%s"' % tag_name,
         'page': the_page,
-        },
-        context_instance=RequestContext(request))
+        })
 
 #######################################################################
 
@@ -225,21 +213,13 @@
     else:
         send_form = SendStoryForm()
 
-    return render_to_response('news/send_story.html', {
+    return render(request, 'news/send_story.html', {
         'send_form': send_form,
         'story': story,
-        },
-        context_instance = RequestContext(request))
+        })
 
 #######################################################################
 
 @login_required
 def email_thanks(request):
-    return render_to_response('news/send_story.html', {
-        },
-        context_instance = RequestContext(request))
-
-#######################################################################
-
-def _clean_html(s):
-    return clean_html(s, profile='news')
+    return render(request, 'news/send_story.html')
--- a/oembed/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/oembed/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,9 +1,12 @@
 """
 URLs for the oembed application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('oembed.views',
-    url(r'^fetch/$', 'fetch_media', name='oembed-fetch_media'),
-    url(r'^fetch_saved/$', 'fetch_saved_media', name='oembed-fetch_saved_media'),
-)
+import oembed.views
+
+
+urlpatterns = [
+    url(r'^fetch/$', oembed.views.fetch_media, name='oembed-fetch_media'),
+    url(r'^fetch_saved/$', oembed.views.fetch_saved_media, name='oembed-fetch_saved_media'),
+]
--- a/podcast/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/podcast/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -2,14 +2,14 @@
 urls for the podcast application
 
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.decorators.cache import cache_page
 
-from podcast.views import feed
+import podcast.views
 
 
-urlpatterns = patterns('podcast.views',
-   url(r'^$', 'index', name='podcast-main'),
-   url(r'^(\d+)/$', 'detail', name='podcast-detail'),
-   url(r'^feed.xml/$', cache_page(3600)(feed), name='podcast-feed'),
-)
+urlpatterns = [
+   url(r'^$', podcast.views.index, name='podcast-main'),
+   url(r'^(\d+)/$', podcast.views.detail, name='podcast-detail'),
+   url(r'^feed.xml/$', cache_page(3600)(podcast.views.feed), name='podcast-feed'),
+]
--- a/polls/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/polls/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,9 +1,12 @@
 """urls for the polls application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('polls.views',
-    url(r'^$', 'poll_index', name='polls-main'),
-    url(r'^(?P<poll_id>\d+)/$', 'poll_detail', name='polls-detail'),
-    url(r'^(?P<poll_id>\d+)/vote/$', 'poll_vote', name='polls-vote'),
-    url(r'^delete_vote/$', 'poll_delete_vote', name='polls-delete_vote'),
-)
+import polls.views
+
+
+urlpatterns = [
+    url(r'^$', polls.views.poll_index, name='polls-main'),
+    url(r'^(?P<poll_id>\d+)/$', polls.views.poll_detail, name='polls-detail'),
+    url(r'^(?P<poll_id>\d+)/vote/$', polls.views.poll_vote, name='polls-vote'),
+    url(r'^delete_vote/$', polls.views.poll_delete_vote, name='polls-delete_vote'),
+]
--- a/potd/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/potd/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,9 +1,12 @@
 """
 URLs for the POTD application.
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('potd.views',
-    url(r'^$', 'view', name='potd-view'),
-    url(r'^archive/(\d+)/$', 'archive', name='potd-archive'),
-)
+import potd.views
+
+
+urlpatterns = [
+    url(r'^$', potd.views.view, name='potd-view'),
+    url(r'^archive/(\d+)/$', potd.views.archive, name='potd-archive'),
+]
--- a/requirements.txt	Mon Dec 14 20:42:20 2015 -0600
+++ b/requirements.txt	Tue Dec 15 21:01:07 2015 -0600
@@ -4,10 +4,10 @@
 bleach==1.4
 boto==2.13.0
 celery==3.1.18
-Django==1.7.11
+Django==1.8.7
 django-haystack==2.3.1
 django-picklefield==0.3.1
-django-tagging==0.3.1
+django-tagging==0.4
 docutils==0.10
 -e git+https://github.com/gremmie/django-elsewhere.git@1203bd331aba4c5d4e702cc4e64d807310f2b591#egg=django_elsewhere-master
 -e git+https://github.com/notanumber/xapian-haystack.git@a3a3a4e7cfba3e2e1be3a42abf59edd29ea03c05#egg=xapian_haystack-master
--- a/requirements_dev.txt	Mon Dec 14 20:42:20 2015 -0600
+++ b/requirements_dev.txt	Tue Dec 15 21:01:07 2015 -0600
@@ -1,6 +1,6 @@
 -r requirements.txt
 Fabric==1.4.1
-django-debug-toolbar==1.3.0
+django-debug-toolbar==1.4
 mock==1.0.1
 pycrypto==2.5
 sqlparse==0.1.14
--- a/sg101/settings/base.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/sg101/settings/base.py	Tue Dec 15 21:01:07 2015 -0600
@@ -11,7 +11,6 @@
 PROJECT_PATH = os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))
 
 DEBUG = True
-TEMPLATE_DEBUG = DEBUG
 
 ADMINS = (
     ('Brian Neal', 'admin@surfguitar101.com'),
@@ -74,6 +73,7 @@
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'core.middleware.InactiveUserMiddleware',
     'core.middleware.WhosOnline',
@@ -83,20 +83,24 @@
 
 ROOT_URLCONF = 'sg101.urls'
 
-TEMPLATE_DIRS = (
-    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
-    # Always use forward slashes, even on Windows.
-    # Don't forget to use absolute paths, not relative paths.
-    os.path.join(PROJECT_PATH, 'templates'),
-)
-
-TEMPLATE_CONTEXT_PROCESSORS = (
-    "django.contrib.auth.context_processors.auth",
-    "django.core.context_processors.debug",
-    "django.core.context_processors.request",
-    "django.core.context_processors.media",
-    "django.contrib.messages.context_processors.messages",
-)
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [
+            os.path.join(PROJECT_PATH, 'templates'),
+        ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                "django.contrib.auth.context_processors.auth",
+                "django.template.context_processors.debug",
+                "django.template.context_processors.request",
+                "django.template.context_processors.media",
+                "django.contrib.messages.context_processors.messages",
+            ],
+        },
+    },
+]
 
 INSTALLED_APPS = [
     'django.contrib.admin',
@@ -365,6 +369,3 @@
         'js/markitup/sets/markdown/style.css',
     ],
 }
-
-# Turn off warning about test runner behavior change
-SILENCED_SYSTEM_CHECKS = ['1_6.W001']
--- a/sg101/settings/local.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/sg101/settings/local.py	Tue Dec 15 21:01:07 2015 -0600
@@ -38,7 +38,7 @@
 
 LOGGING = {
     'version': 1,
-    'disable_existing_loggers': True,
+    'disable_existing_loggers': False,
     'formatters': {
         'verbose': {
             'format': '%(asctime)s %(levelname)s %(module)s %(process)d %(thread)d %(message)s'
--- a/sg101/settings/production.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/sg101/settings/production.py	Tue Dec 15 21:01:07 2015 -0600
@@ -28,7 +28,8 @@
 STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
 
 # Used cached template loader
-TEMPLATE_LOADERS = [
+del TEMPLATES[0]['APP_DIRS']
+TEMPLATES[0]['OPTIONS']['loaders'] = [
     ('django.template.loaders.cached.Loader', (
         'django.template.loaders.filesystem.Loader',
         'django.template.loaders.app_directories.Loader',
--- a/sg101/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/sg101/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,7 +1,8 @@
-from django.conf.urls import patterns, url, include
+from django.conf.urls import url, include
 from django.conf.urls.static import static
 from django.conf import settings
 from django.contrib import admin
+import django.contrib.auth.views
 from django.views.decorators.cache import cache_page
 from django.views.generic import TemplateView
 
@@ -15,7 +16,7 @@
 from core.views import FixedView
 
 
-urlpatterns = patterns('',
+urlpatterns = [
    url(r'^$',
        TemplateView.as_view(template_name='home.html'),
        name='home'),
@@ -32,12 +33,12 @@
        FixedView.as_view(title='Terms of Service', content_template='fixed/tos.html'),
        name='tos'),
 
-   (r'^admin/doc/', include('django.contrib.admindocs.urls')),
+   url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
 
-   url(r'^admin/password_reset/$', 'django.contrib.auth.views.password_reset', name='admin_password_reset'),
-   (r'^admin/password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
-   (r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
-   (r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
+   url(r'^admin/password_reset/$', django.contrib.auth.views.password_reset, name='admin_password_reset'),
+   url(r'^admin/password_reset/done/$', django.contrib.auth.views.password_reset_done),
+   url(r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', django.contrib.auth.views.password_reset_confirm),
+   url(r'^reset/done/$', django.contrib.auth.views.password_reset_complete),
 
    url(r'^store/$',
        TemplateView.as_view(template_name='store/base.html'),
@@ -49,17 +50,17 @@
        TemplateView.as_view(template_name='store/thanks.html'),
        name='store-thanks'),
 
-   (r'^admin/', include(admin.site.urls)),
-   (r'^accounts/', include('accounts.urls')),
-   (r'^antispam/', include('antispam.urls')),
-   (r'^bandmap/', include('bandmap.urls')),
-   (r'^calendar/', include('gcalendar.urls')),
-   (r'^comments/', include('comments.urls')),
-   (r'^contact/', include('contact.urls')),
-   (r'^contests/', include('contests.urls')),
-   (r'^core/', include('core.urls')),
-   (r'^donations/', include('donations.urls')),
-   (r'^downloads/', include('downloads.urls')),
+   url(r'^admin/', include(admin.site.urls)),
+   url(r'^accounts/', include('accounts.urls')),
+   url(r'^antispam/', include('antispam.urls')),
+   url(r'^bandmap/', include('bandmap.urls')),
+   url(r'^calendar/', include('gcalendar.urls')),
+   url(r'^comments/', include('comments.urls')),
+   url(r'^contact/', include('contact.urls')),
+   url(r'^contests/', include('contests.urls')),
+   url(r'^core/', include('core.urls')),
+   url(r'^donations/', include('donations.urls')),
+   url(r'^downloads/', include('downloads.urls')),
    url(r'^feeds/news/$',
        cache_page(6 * 60 * 60)(LatestNewsFeed()),
        name='feeds-news'),
@@ -70,28 +71,28 @@
    url(r'^feeds/forums/(?P<forum_slug>[\w\d-]+)/$',
        cache_page(5 * 60)(ForumsFeed()),
        name='feeds-forum'),
-   (r'^forums/', include('forums.urls')),
-   (r'^irc/', include('irc.urls')),
-   (r'^links/', include('weblinks.urls')),
-   (r'^member_map/', include('membermap.urls')),
-   (r'^messages/', include('messages.urls')),
-   (r'^news/', include('news.urls')),
-   (r'^oembed/', include('oembed.urls')),
-   (r'^podcast/', include('podcast.urls')),
-   (r'^polls/', include('polls.urls')),
-   (r'^potd/', include('potd.urls')),
-   (r'^profile/', include('bio.urls')),
-   (r'^shout/', include('shoutbox.urls')),
-   (r'^smiley/', include('smiley.urls')),
-   (r'^user_photos/', include('user_photos.urls')),
-   (r'^ygroup/', include('ygroup.urls')),
-)
+   url(r'^forums/', include('forums.urls')),
+   url(r'^irc/', include('irc.urls')),
+   url(r'^links/', include('weblinks.urls')),
+   url(r'^member_map/', include('membermap.urls')),
+   url(r'^messages/', include('messages.urls')),
+   url(r'^news/', include('news.urls')),
+   url(r'^oembed/', include('oembed.urls')),
+   url(r'^podcast/', include('podcast.urls')),
+   url(r'^polls/', include('polls.urls')),
+   url(r'^potd/', include('potd.urls')),
+   url(r'^profile/', include('bio.urls')),
+   url(r'^shout/', include('shoutbox.urls')),
+   url(r'^smiley/', include('smiley.urls')),
+   url(r'^user_photos/', include('user_photos.urls')),
+   url(r'^ygroup/', include('ygroup.urls')),
+]
 
 # Haystack search views
 
 sqs = SearchQuerySet().order_by('-pub_date')
 
-urlpatterns += patterns('haystack.views',
+urlpatterns += [
     url(r'^search/$',
         search_view_factory(view_class=UserSearchView,
                             form_class=CustomModelSearchForm,
@@ -105,7 +106,7 @@
                             searchqueryset=sqs,
                             load_all=True),
         name='haystack_search_ajax'),
-)
+]
 
 # For serving media files in development only:
 urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
--- a/shoutbox/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/shoutbox/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -2,14 +2,17 @@
 Urls for the Shoutbox application.
 """
 
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('shoutbox.views',
-    url(r'^delete/$', 'delete', name='shoutbox-delete'),
-    url(r'^edit/$', 'edit', name='shoutbox-edit'),
-    url(r'^flag/$', 'flag', name='shoutbox-flag'),
-    url(r'^shout/$', 'shout', name='shoutbox-shout'),
-    url(r'^text/$', 'text', name='shoutbox-text'),
-    url(r'^view/(\d+)/$', 'view_shout', name='shoutbox-view'),
-    url(r'^view/history/$', 'view_history', name='shoutbox-history'),
-)
+import shoutbox.views
+
+
+urlpatterns = [
+    url(r'^delete/$', shoutbox.views.delete, name='shoutbox-delete'),
+    url(r'^edit/$', shoutbox.views.edit, name='shoutbox-edit'),
+    url(r'^flag/$', shoutbox.views.flag, name='shoutbox-flag'),
+    url(r'^shout/$', shoutbox.views.shout, name='shoutbox-shout'),
+    url(r'^text/$', shoutbox.views.text, name='shoutbox-text'),
+    url(r'^view/(\d+)/$', shoutbox.views.view_shout, name='shoutbox-view'),
+    url(r'^view/history/$', shoutbox.views.view_history, name='shoutbox-history'),
+]
--- a/smiley/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/smiley/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,10 +1,12 @@
 """
 Urls for the Smiley application.
 """
+from django.conf.urls import url
 
-from django.conf.urls import patterns, url
+import smiley.views
 
-urlpatterns = patterns('smiley.views',
-    url(r'^farm/$', 'farm', name='smiley-farm'),
-    url(r'^farm/extra/$', 'farm', kwargs={'extra': True}, name='smiley-farm_extra'),
-)
+
+urlpatterns = [
+    url(r'^farm/$', smiley.views.farm, name='smiley-farm'),
+    url(r'^farm/extra/$', smiley.views.farm, kwargs={'extra': True}, name='smiley-farm_extra'),
+]
--- a/user_photos/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/user_photos/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,24 +1,24 @@
 """URLs for the user_photos application."""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.generic import DetailView
 
 from user_photos.models import Photo
-from user_photos.views import GalleryView
+import user_photos.views
 
 
-urlpatterns = patterns('',
-    url(r'^upload/$', 'user_photos.views.upload', name='user_photos-upload'),
+urlpatterns = [
+    url(r'^upload/$', user_photos.views.upload, name='user_photos-upload'),
     url(r'^upload-ajax/$',
-        'user_photos.views.upload_ajax',
+        user_photos.views.upload_ajax,
         name='user_photos-upload_ajax'),
     url(r'^photo/(?P<pk>\d+)/$',
         DetailView.as_view(model=Photo),
         name='user_photos-detail'),
     url(r'^gallery/(?P<username>[\w.@+-]{1,30})/$',
-        GalleryView.as_view(),
+        user_photos.views.GalleryView.as_view(),
         name='user_photos-gallery'),
-    url(r'^delete/$', 'user_photos.views.delete', name='user_photos-delete'),
+    url(r'^delete/$', user_photos.views.delete, name='user_photos-delete'),
     url(r'^hotlink/$',
-        'user_photos.views.hotlink_image',
+        user_photos.views.hotlink_image,
         name='user_photos-hotlink'),
-)
+]
--- a/weblinks/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/weblinks/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -1,19 +1,22 @@
 """urls for the weblinks application"""
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 
-urlpatterns = patterns('weblinks.views',
-   url(r'^$', 'link_index', name='weblinks-main'),
-   url(r'^add/$', 'add_link', name='weblinks-add_link'),
-   url(r'^add/thanks/$', 'add_thanks', name='weblinks-add_thanks'),
-   url(r'^category/(?P<slug>[\w\d-]+)/(?P<sort>title|date|rating|hits)/$', 
-      'view_links',
+import weblinks.views as wv
+
+
+urlpatterns = [
+   url(r'^$', wv.link_index, name='weblinks-main'),
+   url(r'^add/$', wv.add_link, name='weblinks-add_link'),
+   url(r'^add/thanks/$', wv.add_thanks, name='weblinks-add_thanks'),
+   url(r'^category/(?P<slug>[\w\d-]+)/(?P<sort>title|date|rating|hits)/$',
+      wv.view_links,
       name='weblinks-view_links'),
-   url(r'^detail/(\d+)/$', 
-      'link_detail',
+   url(r'^detail/(\d+)/$',
+      wv.link_detail,
       name='weblinks-link_detail'),
-   url(r'^new/$', 'new_links', name='weblinks-new_links'),
-   url(r'^popular/$', 'popular_links', name='weblinks-popular_links'),
-   url(r'^random/$', 'random_link', name='weblinks-random_link'),
-   url(r'^report/(\d+)/$', 'report_link', name='weblinks-report_link'),
-   url(r'^visit/(\d+)/$', 'visit', name="weblinks-visit"),
-)
+   url(r'^new/$', wv.new_links, name='weblinks-new_links'),
+   url(r'^popular/$', wv.popular_links, name='weblinks-popular_links'),
+   url(r'^random/$', wv.random_link, name='weblinks-random_link'),
+   url(r'^report/(\d+)/$', wv.report_link, name='weblinks-report_link'),
+   url(r'^visit/(\d+)/$', wv.visit, name="weblinks-visit"),
+]
--- a/ygroup/urls.py	Mon Dec 14 20:42:20 2015 -0600
+++ b/ygroup/urls.py	Tue Dec 15 21:01:07 2015 -0600
@@ -2,14 +2,14 @@
 urls.py - URLs for the ygroup application.
 
 """
-from django.conf.urls import patterns, url
+from django.conf.urls import url
 from django.views.generic import DetailView
 
 from ygroup.models import Post
 from ygroup.views import ThreadIndexView, ThreadView
 
 
-urlpatterns = patterns('',
+urlpatterns = [
     url(r'^threads/$',
         ThreadIndexView.as_view(),
         name='ygroup-thread_index'),
@@ -19,5 +19,4 @@
     url(r'^post/(?P<pk>\d+)/$',
         DetailView.as_view(model=Post, context_object_name='post'),
         name='ygroup-post_view'),
-)
-
+]