changeset 1206:02181fa5ac9d modernize tip

Update to Django 1.9.
author Brian Neal <bgneal@gmail.com>
date Wed, 22 Jan 2025 17:58:16 -0600
parents 510ef3cbf3e6
children
files accounts/__init__.py accounts/admin.py accounts/utils.py accounts/views.py antispam/apps.py bandmap/models.py banners/models.py bio/models.py bio/tests/test_views.py comments/migrations/0001_initial.py comments/models.py comments/views.py contests/templatetags/contest_tags.py core/templatetags/core_tags.py countdown/templatetags/countdown_tags.py donations/models.py donations/templatetags/donations_tags.py downloads/migrations/0001_initial.py downloads/models.py forums/migrations/0001_initial.py forums/models.py forums/tests/test_views.py gcalendar/models.py irc/templatetags/irc_tags.py membermap/models.py messages/models.py messages/templatetags/messages_tags.py news/migrations/0001_initial.py news/models.py news/tests/test_views.py podcast/models.py polls/models.py polls/templatetags/poll_tags.py polls/tests/test_views.py potd/models.py potd/templatetags/potd_tags.py requirements.txt sg101/urls.py shoutbox/models.py user_photos/models.py weblinks/models.py ygroup/models.py
diffstat 42 files changed, 213 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/accounts/__init__.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/accounts/__init__.py	Wed Jan 22 17:58:16 2025 -0600
@@ -1,40 +0,0 @@
-import datetime
-import logging
-
-from django.contrib.auth.models import User
-
-
-logger = logging.getLogger('auth')
-
-
-def create_new_user(pending_user, ip=None, admin_activation=False):
-    """
-    This function contains the code to create a new user from a
-    pending user. The pending user is deleted and the new user
-    is saved. A log message is produced. If admin_activation is false,
-    then ip should be the user's IP they confirmed from, if available.
-
-    """
-    new_user = User()
-
-    new_user.username = pending_user.username
-    new_user.first_name = ''
-    new_user.last_name = ''
-    new_user.email = pending_user.email
-    new_user.password = pending_user.password     # already been hashed
-    new_user.is_staff = False
-    new_user.is_active = True
-    new_user.is_superuser = False
-    new_user.last_login = datetime.datetime.now()
-    new_user.date_joined = new_user.last_login
-
-    new_user.save()
-    pending_user.delete()
-
-    if admin_activation:
-        msg = 'Accounts registration confirmed by ADMIN for %s' % new_user.username
-    else:
-        msg = 'Accounts registration confirmed by USER for %s from %s' % (
-                new_user.username, ip)
-
-    logger.info(msg)
--- a/accounts/admin.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/accounts/admin.py	Wed Jan 22 17:58:16 2025 -0600
@@ -4,7 +4,7 @@
 from accounts.models import IllegalUsername
 from accounts.models import IllegalEmail
 from accounts.models import PendingUser
-from accounts import create_new_user
+from accounts.utils import create_new_user
 
 
 class PendingUserAdmin(admin.ModelAdmin):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accounts/utils.py	Wed Jan 22 17:58:16 2025 -0600
@@ -0,0 +1,40 @@
+import datetime
+import logging
+
+from django.contrib.auth.models import User
+
+
+logger = logging.getLogger('auth')
+
+
+def create_new_user(pending_user, ip=None, admin_activation=False):
+    """
+    This function contains the code to create a new user from a
+    pending user. The pending user is deleted and the new user
+    is saved. A log message is produced. If admin_activation is false,
+    then ip should be the user's IP they confirmed from, if available.
+
+    """
+    new_user = User()
+
+    new_user.username = pending_user.username
+    new_user.first_name = ''
+    new_user.last_name = ''
+    new_user.email = pending_user.email
+    new_user.password = pending_user.password     # already been hashed
+    new_user.is_staff = False
+    new_user.is_active = True
+    new_user.is_superuser = False
+    new_user.last_login = datetime.datetime.now()
+    new_user.date_joined = new_user.last_login
+
+    new_user.save()
+    pending_user.delete()
+
+    if admin_activation:
+        msg = 'Accounts registration confirmed by ADMIN for %s' % new_user.username
+    else:
+        msg = 'Accounts registration confirmed by USER for %s from %s' % (
+                new_user.username, ip)
+
+    logger.info(msg)
--- a/accounts/views.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/accounts/views.py	Wed Jan 22 17:58:16 2025 -0600
@@ -14,7 +14,7 @@
 from accounts.forms import RegisterForm
 from accounts.forms import RegisterCodeForm
 from accounts.forms import ForgotUsernameForm
-from accounts import create_new_user
+from accounts.utils import create_new_user
 from antispam.decorators import log_auth_failures
 
 
--- a/antispam/apps.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/antispam/apps.py	Wed Jan 22 17:58:16 2025 -0600
@@ -1,7 +1,4 @@
 from django.apps import AppConfig
-import django.contrib.auth.views
-
-from antispam.decorators import log_auth_failures
 
 
 class AntiSpamConfig(AppConfig):
@@ -10,6 +7,8 @@
 
     def ready(self):
         import antispam.receivers
+        from antispam.decorators import log_auth_failures
+        import django.contrib.auth.views
 
         # Install rate limiting on auth login
         django.contrib.auth.views.login = log_auth_failures('Login')(
--- a/bandmap/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/bandmap/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -16,7 +16,7 @@
 class BandEntry(models.Model):
     """Represents a band entry on the band map."""
     name = models.CharField(max_length=128)
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     date_submitted = models.DateTimeField()
     date_approved = models.DateTimeField(null=True, blank=True)
     url = models.URLField(blank=True, max_length=200)
--- a/banners/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/banners/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -42,7 +42,7 @@
     A model to represent a banner.
 
     """
-    campaign = models.ForeignKey(Campaign)
+    campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
     image = models.ImageField(upload_to=banner_upload_to)
     description = models.CharField(max_length=128)
     creation_date = models.DateTimeField(blank=True)
--- a/bio/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/bio/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -80,7 +80,8 @@
 class UserProfile(models.Model):
     """model to represent additional information about users"""
 
-    user = models.OneToOneField(User, related_name='profile')
+    user = models.OneToOneField(User, related_name='profile',
+                                on_delete=models.CASCADE)
     location = models.CharField(max_length=128, blank=True)
     country = models.CharField(max_length=2, blank=True, default='',
             choices=bio.flags.FLAG_CHOICES,
@@ -184,8 +185,8 @@
 
 class UserProfileFlag(models.Model):
     """This model represents a user flagging a profile as inappropriate."""
-    user = models.ForeignKey(User)
-    profile = models.ForeignKey(UserProfile)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
     flag_date = models.DateTimeField(auto_now_add=True)
 
     def __unicode__(self):
@@ -202,8 +203,8 @@
 
 class BadgeOwnership(models.Model):
     """This model represents the ownership of badges by users."""
-    profile = models.ForeignKey(UserProfile)
-    badge = models.ForeignKey(Badge)
+    profile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
+    badge = models.ForeignKey(Badge, on_delete=models.CASCADE)
     count = models.IntegerField(default=1)
 
     class Meta:
--- a/bio/tests/test_views.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/bio/tests/test_views.py	Wed Jan 22 17:58:16 2025 -0600
@@ -44,8 +44,10 @@
 
         self.assertEqual(len(response.redirect_chain), 1)
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                    'http://testserver' + reverse('bio-view_profile',
+            self.assertEqual(
+                    response.redirect_chain[0][0],
+                    reverse(
+                        'bio-view_profile',
                         kwargs={'username': self.USERNAME}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
@@ -76,8 +78,10 @@
 
         self.assertEqual(len(response.redirect_chain), 1)
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                    'http://testserver' + reverse('bio-view_profile',
+            self.assertEqual(
+                    response.redirect_chain[0][0],
+                    reverse(
+                        'bio-view_profile',
                         kwargs={'username': self.USERNAME}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
--- a/comments/migrations/0001_initial.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/comments/migrations/0001_initial.py	Wed Jan 22 17:58:16 2025 -0600
@@ -24,8 +24,8 @@
                 ('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)),
+                ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('creation_date',),
@@ -36,8 +36,10 @@
             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)),
+                ('comment', models.ForeignKey(to='comments.Comment',
+                                              on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('flag_date',),
--- a/comments/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/comments/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -30,10 +30,10 @@
 
 class Comment(models.Model):
     """My own version of a Comment class that can attach comments to any other model."""
-    content_type = models.ForeignKey(ContentType)
+    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
     object_id = models.PositiveIntegerField(db_index=True)
     content_object = GenericForeignKey('content_type', 'object_id')
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     comment = models.TextField(max_length=COMMENT_MAX_LENGTH)
     html = models.TextField(blank=True)
     creation_date = models.DateTimeField()
@@ -85,8 +85,8 @@
 
 class CommentFlag(models.Model):
     """This model represents a user flagging a comment as inappropriate."""
-    user = models.ForeignKey(User)
-    comment = models.ForeignKey(Comment)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    comment = models.ForeignKey(Comment, on_delete=models.CASCADE)
     flag_date = models.DateTimeField(auto_now_add=True)
 
     def __unicode__(self):
--- a/comments/views.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/comments/views.py	Wed Jan 22 17:58:16 2025 -0600
@@ -2,12 +2,12 @@
 Views for the comments application.
 
 """
+from django.apps import apps
 from django.contrib.auth.decorators import login_required
 from django.core.exceptions import ObjectDoesNotExist
 from django.http import HttpResponse
 from django.http import HttpResponseBadRequest
 from django.http import HttpResponseForbidden
-from django.db.models import get_model
 from django.shortcuts import render
 from django.utils.html import escape
 from django.views.decorators.http import require_POST
@@ -51,7 +51,7 @@
         return HttpResponseBadRequest('Missing content_type or object_pk field.')
 
     try:
-        model = get_model(*ctype.split('.', 1))
+        model = apps.get_model(*ctype.split('.', 1))
         target = model.objects.get(pk=object_pk)
     except TypeError:
         return HttpResponseBadRequest(
--- a/contests/templatetags/contest_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/contests/templatetags/contest_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -19,4 +19,4 @@
 
     with context.push():
         context['contests'] = contests
-        return t.render(context)
+        return t.render(context.flatten())
--- a/core/templatetags/core_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/core/templatetags/core_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -78,7 +78,7 @@
         context['title'] = title
         context['url'] = url
         context['center'] = center
-        return t.render(context)
+        return t.render(context.flatten())
 
 
 def _fully_qualify(url, domain):
@@ -185,7 +185,7 @@
     template_name = ('core/v3/birthday_block.html'
             if 'V3_DESIGN' in context else 'core/birthday_block.html')
     t = template.loader.get_template(template_name)
-    return t.render(context)
+    return t.render(context.flatten())
 
 
 class EncodeParamsNode(template.Node):
--- a/countdown/templatetags/countdown_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/countdown/templatetags/countdown_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -25,4 +25,4 @@
     t = template.loader.get_template(template_name)
     with context.push():
         context['events'] = results
-        return t.render(context)
+        return t.render(context.flatten())
--- a/donations/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/donations/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -95,7 +95,8 @@
 class Donation(models.Model):
     """Model to represent a donation to the website."""
 
-    user = models.ForeignKey(User, null=True, blank=True)
+    user = models.ForeignKey(User, null=True, blank=True,
+                             on_delete=models.CASCADE)
     is_anonymous = models.BooleanField(default=False)
     test_ipn = models.BooleanField(default=False, verbose_name="Test IPN")
     txn_id = models.CharField(max_length=20, verbose_name="Txn ID")
--- a/donations/templatetags/donations_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/donations/templatetags/donations_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -18,7 +18,7 @@
 
     with context.push():
         context['pct'] = Donation.objects.monthly_goal_pct()
-        return t.render(context)
+        return t.render(context.flatten())
 
 
 @register.inclusion_tag('donations/top_donors_tag.html')
--- a/downloads/migrations/0001_initial.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/downloads/migrations/0001_initial.py	Wed Jan 22 17:58:16 2025 -0600
@@ -52,8 +52,10 @@
                 ('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)),
+                ('category', models.ForeignKey(to='downloads.Category',
+                                               on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'abstract': False,
@@ -70,8 +72,10 @@
                 ('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)),
+                ('category', models.ForeignKey(to='downloads.Category',
+                                               on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('date_added',),
@@ -82,8 +86,10 @@
             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)),
+                ('download', models.ForeignKey(to='downloads.Download',
+                                               on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('-vote_date',),
--- a/downloads/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/downloads/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -52,11 +52,11 @@
 class DownloadBase(models.Model):
     """Abstract model to collect common download fields."""
     title = models.CharField(max_length=128)
-    category = models.ForeignKey(Category)
+    category = models.ForeignKey(Category, on_delete=models.CASCADE)
     description = models.TextField()
     html = models.TextField(blank=True)
     file = models.FileField(upload_to=download_path)
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     date_added = models.DateTimeField(db_index=True)
     ip_address = models.GenericIPAddressField('IP Address')
     update_date = models.DateTimeField(db_index=True, blank=True)
@@ -147,8 +147,8 @@
 
 class VoteRecord(models.Model):
     """Model to record the date that a user voted on a download."""
-    download = models.ForeignKey(Download)
-    user = models.ForeignKey(User)
+    download = models.ForeignKey(Download, on_delete=models.CASCADE)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     vote_date = models.DateTimeField(auto_now_add=True)
 
     def __unicode__(self):
--- a/forums/migrations/0001_initial.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/forums/migrations/0001_initial.py	Wed Jan 22 17:58:16 2025 -0600
@@ -19,7 +19,8 @@
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('order', models.IntegerField()),
-                ('embed', models.ForeignKey(to='oembed.Oembed')),
+                ('embed', models.ForeignKey(to='oembed.Oembed',
+                                            on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('order',),
@@ -59,7 +60,9 @@
                 ('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')),
+                ('category', models.ForeignKey(related_name='forums',
+                                               to='forums.Category',
+                                               on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('position',),
@@ -71,8 +74,10 @@
                 ('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)),
+                ('forum', models.ForeignKey(to='forums.Forum',
+                                            on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('-end_date',),
@@ -108,10 +113,16 @@
                 ('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')),
+                ('forum', models.ForeignKey(related_name='topics',
+                                            to='forums.Forum',
+                                            on_delete=models.CASCADE)),
+                ('last_post', models.OneToOneField(related_name='parent_topic',
+                                                   null=True, blank=True,
+                                                   to='forums.Post',
+                                                   on_delete=models.CASCADE)),
                 ('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)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('-sticky', '-update_date'),
@@ -122,8 +133,10 @@
             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)),
+                ('topic', models.ForeignKey(to='forums.Topic',
+                                            on_delete=models.CASCADE)),
+                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                           on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('-last_visit',),
@@ -132,17 +145,22 @@
         migrations.AddField(
             model_name='post',
             name='topic',
-            field=models.ForeignKey(related_name='posts', to='forums.Topic'),
+            field=models.ForeignKey(related_name='posts', to='forums.Topic',
+                                    on_delete=models.CASCADE),
         ),
         migrations.AddField(
             model_name='post',
             name='user',
-            field=models.ForeignKey(related_name='posts', to=settings.AUTH_USER_MODEL),
+            field=models.ForeignKey(related_name='posts',
+                                    to=settings.AUTH_USER_MODEL,
+                                    on_delete=models.CASCADE),
         ),
         migrations.AddField(
             model_name='forum',
             name='last_post',
-            field=models.OneToOneField(related_name='parent_forum', null=True, blank=True, to='forums.Post'),
+            field=models.OneToOneField(related_name='parent_forum', null=True,
+                                       blank=True, to='forums.Post',
+                                       on_delete=models.CASCADE),
         ),
         migrations.AddField(
             model_name='forum',
@@ -152,17 +170,18 @@
         migrations.AddField(
             model_name='flaggedpost',
             name='post',
-            field=models.ForeignKey(to='forums.Post'),
+            field=models.ForeignKey(to='forums.Post', on_delete=models.CASCADE),
         ),
         migrations.AddField(
             model_name='flaggedpost',
             name='user',
-            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
+            field=models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                    on_delete=models.CASCADE),
         ),
         migrations.AddField(
             model_name='attachment',
             name='post',
-            field=models.ForeignKey(to='forums.Post'),
+            field=models.ForeignKey(to='forums.Post', on_delete=models.CASCADE),
         ),
         migrations.AlterUniqueTogether(
             name='topiclastvisit',
--- a/forums/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/forums/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -82,7 +82,8 @@
     """
     A forum is a collection of topics.
     """
-    category = models.ForeignKey(Category, related_name='forums')
+    category = models.ForeignKey(Category, related_name='forums',
+                                 on_delete=models.CASCADE)
     name = models.CharField(max_length=80)
     slug = models.SlugField(max_length=80)
     description = models.TextField(blank=True, default='')
@@ -92,8 +93,9 @@
     # denormalized fields to reduce database hits
     topic_count = models.IntegerField(blank=True, default=0)
     post_count = models.IntegerField(blank=True, default=0)
-    last_post = models.OneToOneField('Post', blank=True, null=True,
-        related_name='parent_forum')
+    last_post = models.OneToOneField(
+            'Post', blank=True, null=True, related_name='parent_forum',
+            on_delete=models.CASCADE)
 
     objects = ForumManager()
 
@@ -170,10 +172,11 @@
     """
     A topic is a thread of discussion, consisting of a series of posts.
     """
-    forum = models.ForeignKey(Forum, related_name='topics')
+    forum = models.ForeignKey(Forum, related_name='topics',
+                              on_delete=models.CASCADE)
     name = models.CharField(max_length=255)
     creation_date = models.DateTimeField(db_index=True)
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     view_count = models.IntegerField(blank=True, default=0)
     sticky = models.BooleanField(blank=True, default=False)
     locked = models.BooleanField(blank=True, default=False)
@@ -185,8 +188,9 @@
     # denormalized fields to reduce database hits
     post_count = models.IntegerField(blank=True, default=0)
     update_date = models.DateTimeField(db_index=True)
-    last_post = models.OneToOneField('Post', blank=True, null=True,
-        related_name='parent_topic')
+    last_post = models.OneToOneField(
+            'Post', blank=True, null=True, related_name='parent_topic',
+            on_delete=models.CASCADE)
 
     class Meta:
         ordering = ('-sticky', '-update_date', )
@@ -276,8 +280,10 @@
     """
     A post is an instance of a user's single contribution to a topic.
     """
-    topic = models.ForeignKey(Topic, related_name='posts')
-    user = models.ForeignKey(User, related_name='posts')
+    topic = models.ForeignKey(Topic, related_name='posts',
+                              on_delete=models.CASCADE)
+    user = models.ForeignKey(User, related_name='posts',
+                             on_delete=models.CASCADE)
     creation_date = models.DateTimeField(db_index=True)
     update_date = models.DateTimeField(db_index=True)
     body = models.TextField()
@@ -336,8 +342,8 @@
 
 class FlaggedPost(models.Model):
     """This model represents a user flagging a post as inappropriate."""
-    user = models.ForeignKey(User)
-    post = models.ForeignKey(Post)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    post = models.ForeignKey(Post, on_delete=models.CASCADE)
     flag_date = models.DateTimeField(auto_now_add=True)
 
     def __unicode__(self):
@@ -360,8 +366,8 @@
     objects.
     Marking a forum as all read sets the begin_date equal to the end_date.
     """
-    user = models.ForeignKey(User)
-    forum = models.ForeignKey(Forum)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    forum = models.ForeignKey(Forum, on_delete=models.CASCADE)
     begin_date = models.DateTimeField()
     end_date = models.DateTimeField()
 
@@ -383,8 +389,8 @@
     Objects of this class exist for the window specified in the
     corresponding ForumLastVisit object.
     """
-    user = models.ForeignKey(User)
-    topic = models.ForeignKey(Topic)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
     last_visit = models.DateTimeField(db_index=True)
 
     class Meta:
@@ -409,8 +415,8 @@
     This model is a "through" table for the M2M relationship between forum
     posts and Oembed objects.
     """
-    post = models.ForeignKey(Post)
-    embed = models.ForeignKey(Oembed)
+    post = models.ForeignKey(Post, on_delete=models.CASCADE)
+    embed = models.ForeignKey(Oembed, on_delete=models.CASCADE)
     order = models.IntegerField()
 
     class Meta:
--- a/forums/tests/test_views.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/forums/tests/test_views.py	Wed Jan 22 17:58:16 2025 -0600
@@ -37,9 +37,9 @@
         self.assertEqual(len(response.redirect_chain), 1)
 
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                'http://testserver' + reverse('forums-new_topic_thanks',
-                    kwargs={'tid': '1'}))
+            self.assertEqual(
+                response.redirect_chain[0][0],
+                reverse('forums-new_topic_thanks', kwargs={'tid': '1'}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
         self.assertEqual(response.status_code, 200)
--- a/gcalendar/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/gcalendar/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -41,7 +41,7 @@
         (ON_CAL, 'On Calendar'),
     )
 
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     what = models.CharField(max_length=255)
     start_date = models.DateField()
     start_time = models.TimeField(null=True, blank=True)
--- a/irc/templatetags/irc_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/irc/templatetags/irc_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -13,4 +13,4 @@
     t = template.loader.get_template(template_name)
     with context.push():
         context['nicks'] = get_users()
-        return t.render(context)
+        return t.render(context.flatten())
--- a/membermap/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/membermap/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -10,7 +10,7 @@
 
 class MapEntry(models.Model):
     """Represents a user's entry on the map."""
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     location = models.CharField(max_length=255)
     lat = models.FloatField()
     lon = models.FloatField()
--- a/messages/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/messages/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -32,8 +32,10 @@
 
 class Message(models.Model):
     """The Message is a model for a private message between users."""
-    sender = models.ForeignKey(User, related_name='sender')
-    receiver = models.ForeignKey(User, related_name='receiver')
+    sender = models.ForeignKey(User, related_name='sender',
+                               on_delete=models.CASCADE)
+    receiver = models.ForeignKey(User, related_name='receiver',
+                                 on_delete=models.CASCADE)
     send_date = models.DateTimeField('Date Sent', null=True, blank=True)
     read_date = models.DateTimeField('Date Received', null=True, blank=True)
     reply_date = models.DateTimeField('Date Replied', null=True, blank=True)
@@ -91,7 +93,7 @@
 
 class Options(models.Model):
     """Options is a model for user private message options."""
-    user = models.ForeignKey(User, editable=False)
+    user = models.ForeignKey(User, editable=False, on_delete=models.CASCADE)
     attach_signature = models.BooleanField("Always attach signature?", default=True)
     notify_email = models.BooleanField("Notify me of new messages via email?", default=False)
 
@@ -109,7 +111,7 @@
     has flagged the message for spam or abuse.
 
     """
-    message = models.OneToOneField(Message)
+    message = models.OneToOneField(Message, on_delete=models.CASCADE)
     flag_date = models.DateTimeField()
     comments = models.TextField(blank=True)
 
--- a/messages/templatetags/messages_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/messages/templatetags/messages_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -22,7 +22,7 @@
     template_name = ('messages/v3/unread_messages_tag.html'
             if 'V3_DESIGN' in context else 'messages/unread_messages_tag.html')
     t = template.loader.get_template(template_name)
-    return t.render(context)
+    return t.render(context.flatten())
 
 
 @register.simple_tag
--- a/news/migrations/0001_initial.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/news/migrations/0001_initial.py	Wed Jan 22 17:58:16 2025 -0600
@@ -41,8 +41,10 @@
                 ('update_date', models.DateTimeField(db_index=True, blank=True)),
                 ('priority', models.IntegerField(default=0, db_index=True, blank=True)),
                 ('meta_description', models.TextField(blank=True)),
-                ('category', models.ForeignKey(to='news.Category')),
-                ('submitter', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+                ('category', models.ForeignKey(to='news.Category',
+                                               on_delete=models.CASCADE)),
+                ('submitter', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                                on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('-date_submitted',),
@@ -64,8 +66,10 @@
                 ('update_date', models.DateTimeField(db_index=True, blank=True)),
                 ('priority', models.IntegerField(default=0, db_index=True, blank=True)),
                 ('meta_description', models.TextField(blank=True)),
-                ('category', models.ForeignKey(to='news.Category')),
-                ('submitter', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+                ('category', models.ForeignKey(to='news.Category',
+                                               on_delete=models.CASCADE)),
+                ('submitter', models.ForeignKey(to=settings.AUTH_USER_MODEL,
+                                                on_delete=models.CASCADE)),
             ],
             options={
                 'ordering': ('-date_submitted',),
--- a/news/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/news/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -42,8 +42,8 @@
 class StoryBase(models.Model):
     """Abstract model to collect common fields."""
     title = models.CharField(max_length=255)
-    submitter = models.ForeignKey(User)
-    category = models.ForeignKey(Category)
+    submitter = models.ForeignKey(User, on_delete=models.CASCADE)
+    category = models.ForeignKey(Category, on_delete=models.CASCADE)
     short_text = models.TextField(default='', blank=True)
     long_text = models.TextField(default='', blank=True)
     date_submitted = models.DateTimeField(db_index=True)
--- a/news/tests/test_views.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/news/tests/test_views.py	Wed Jan 22 17:58:16 2025 -0600
@@ -44,7 +44,7 @@
         response = self.client.post(self.view_url, args, follow=True)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.redirect_chain,
-                         [('http://testserver' + reverse('news-submit_thanks'), 302)])
+                         [(reverse('news-submit_thanks'), 302)])
 
         stories = list(PendingStory.objects.all())
         self.assertEqual(len(stories), 1)
--- a/podcast/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/podcast/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -38,7 +38,7 @@
 
 class Item(models.Model):
     """Model to represent a channel item"""
-    channel = models.ForeignKey(Channel)
+    channel = models.ForeignKey(Channel, on_delete=models.CASCADE)
     title = models.CharField(max_length=255)
     author = models.CharField(max_length=255)
     subtitle = models.CharField(max_length=255)
--- a/polls/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/polls/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -89,7 +89,7 @@
 
 class Choice(models.Model):
     """Model for poll choices"""
-    poll = models.ForeignKey(Poll)
+    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
     choice = models.CharField(max_length=200)
     votes = models.IntegerField(default=0)
     voters = models.ManyToManyField(User, blank=True)
--- a/polls/templatetags/poll_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/polls/templatetags/poll_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -26,4 +26,4 @@
     t = template.loader.get_template(template_name)
     with context.push():
         context['polls'] = polls
-        return t.render(context)
+        return t.render(context.flatten())
--- a/polls/tests/test_views.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/polls/tests/test_views.py	Wed Jan 22 17:58:16 2025 -0600
@@ -99,8 +99,9 @@
 
         self.assertEqual(len(response.redirect_chain), 1)
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                    'http://testserver' + reverse('polls-detail', kwargs={'poll_id': poll.id}))
+            self.assertEqual(
+                    response.redirect_chain[0][0],
+                    reverse('polls-detail', kwargs={'poll_id': poll.id}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
         self.assertEqual(response.status_code, 200)
@@ -120,8 +121,9 @@
 
         self.assertEqual(len(response.redirect_chain), 1)
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                'http://testserver' + reverse('polls-detail', kwargs={'poll_id': poll.id}))
+            self.assertEqual(
+                    response.redirect_chain[0][0],
+                    reverse('polls-detail', kwargs={'poll_id': poll.id}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
         self.assertEqual(response.status_code, 404)
@@ -146,8 +148,9 @@
 
         self.assertEqual(len(response.redirect_chain), 1)
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                'http://testserver' + reverse('polls-detail', kwargs={'poll_id': poll.id}))
+            self.assertEqual(
+                    response.redirect_chain[0][0],
+                    reverse('polls-detail', kwargs={'poll_id': poll.id}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
         self.assertEqual(response.status_code, 200)
@@ -165,8 +168,9 @@
 
         self.assertEqual(len(response.redirect_chain), 1)
         if response.redirect_chain:
-            self.assertEqual(response.redirect_chain[0][0],
-                'http://testserver' + reverse('polls-detail', kwargs={'poll_id': poll.id}))
+            self.assertEqual(
+                    response.redirect_chain[0][0],
+                    reverse('polls-detail', kwargs={'poll_id': poll.id}))
             self.assertEqual(response.redirect_chain[0][1], 302)
 
         self.assertEqual(response.status_code, 200)
--- a/potd/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/potd/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -33,7 +33,8 @@
     thumb = models.ImageField(upload_to='potd/%Y/%m/%d/thumbs', blank=True, null=True)
     caption = models.CharField(max_length=128)
     description = models.TextField()
-    user = models.ForeignKey(User, related_name='potd_set')
+    user = models.ForeignKey(User, related_name='potd_set',
+                             on_delete=models.CASCADE)
     date_added = models.DateField()
     potd_count = models.IntegerField(default=0)
 
@@ -115,7 +116,7 @@
 
 class Current(models.Model):
     """This model simply stores the current POTD."""
-    potd = models.ForeignKey(Photo)
+    potd = models.ForeignKey(Photo, on_delete=models.CASCADE)
 
     objects = CurrentManager()
 
--- a/potd/templatetags/potd_tags.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/potd/templatetags/potd_tags.py	Wed Jan 22 17:58:16 2025 -0600
@@ -14,4 +14,4 @@
     t = template.loader.get_template(template_name)
     with context.push():
         context['potd'] = potd
-        return t.render(context)
+        return t.render(context.flatten())
--- a/requirements.txt	Sat Jan 04 21:34:31 2025 -0600
+++ b/requirements.txt	Wed Jan 22 17:58:16 2025 -0600
@@ -4,14 +4,11 @@
 bleach==1.4
 boto==2.13.0
 celery==3.1.23
-Django==1.8.15
+Django==1.9.13
 # TODO SEARCH django-haystack==2.4.1
 django-picklefield==0.3.1
-django-tagging==0.4
+django-tagging==0.4.3
 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-dev
--e hg+ssh://brian@bobcat//svr/dvcs/hg/repos/public/queues@862e8846f7e5f5a0df7f08bfe4b4e5283acb4614#egg=queues-dev
 ftfy==2.0.1
 google-api-python-client==1.3.1
 html5lib==1.0b3
@@ -19,8 +16,7 @@
 kombu==3.0.36
 lxml==3.4.2
 Markdown==2.5.1
-#MySQL-python==1.2.5
-mysqlclient
+mysqlclient==1.4.6
 oauth2client==1.4.1
 Pillow==2.7.0
 pyasn1==0.1.7
@@ -36,3 +32,6 @@
 simplejson==3.6.5
 six==1.8.0
 uritemplate==0.6
+-e git+https://github.com/gremmie/django-elsewhere.git@42503b48cb770cca77c2757d26a6bee9bc10c9da#egg=django_elsewhere
+-e hg+ssh://brian@bobcat//svr/dvcs/hg/repos/public/queues@862e8846f7e5f5a0df7f08bfe4b4e5283acb4614#egg=queues
+-e git+https://github.com/notanumber/xapian-haystack.git@a3a3a4e7cfba3e2e1be3a42abf59edd29ea03c05#egg=xapian_haystack
--- a/sg101/urls.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/sg101/urls.py	Wed Jan 22 17:58:16 2025 -0600
@@ -46,7 +46,7 @@
        StoreView.as_view(),
        name='store'),
 
-   url(r'^admin/', include(admin.site.urls)),
+   url(r'^admin/', admin.site.urls),
    url(r'^accounts/', include('accounts.urls')),
    url(r'^antispam/', include('antispam.urls')),
    url(r'^bandmap/', include('bandmap.urls')),
--- a/shoutbox/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/shoutbox/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -12,7 +12,7 @@
 
 
 class Shout(models.Model):
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     shout_date = models.DateTimeField(blank=True)
     shout = models.TextField()
     html = models.TextField()
@@ -38,8 +38,8 @@
 
 class ShoutFlag(models.Model):
     """This model represents a user flagging a shout as inappropriate."""
-    user = models.ForeignKey(User)
-    shout = models.ForeignKey(Shout)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    shout = models.ForeignKey(Shout, on_delete=models.CASCADE)
     flag_date = models.DateTimeField(auto_now_add=True)
 
     def __unicode__(self):
--- a/user_photos/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/user_photos/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -10,7 +10,8 @@
 class Photo(models.Model):
     """This model represents data about a user uploaded photo."""
     user = models.ForeignKey(settings.AUTH_USER_MODEL,
-                             related_name='uploaded_photos')
+                             related_name='uploaded_photos',
+                             on_delete=models.CASCADE)
     upload_date = models.DateTimeField()
     url = models.URLField(max_length=200)
     thumb_url = models.URLField(max_length=200, blank=True)
--- a/weblinks/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/weblinks/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -32,11 +32,11 @@
 
 class LinkBase(models.Model):
     """Abstract model to aggregate common fields of a web link."""
-    category = models.ForeignKey(Category)
+    category = models.ForeignKey(Category, on_delete=models.CASCADE)
     title = models.CharField(max_length=128)
     url = models.URLField(db_index=True)
     description = models.TextField(blank=True)
-    user = models.ForeignKey(User)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     date_added = models.DateTimeField(db_index=True)
     update_date = models.DateTimeField(db_index=True, blank=True)
 
@@ -108,8 +108,8 @@
 
 class FlaggedLink(models.Model):
     """Model to represent links that have been flagged as broken by users"""
-    link = models.ForeignKey(Link)
-    user = models.ForeignKey(User)
+    link = models.ForeignKey(Link, on_delete=models.CASCADE)
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
     date_flagged = models.DateField(auto_now_add = True)
     approved = models.BooleanField(default = False,
         help_text = 'Check this and save to remove the referenced link from the database')
--- a/ygroup/models.py	Sat Jan 04 21:34:31 2025 -0600
+++ b/ygroup/models.py	Wed Jan 22 17:58:16 2025 -0600
@@ -26,7 +26,8 @@
 
 
 class Post(models.Model):
-    thread = models.ForeignKey(Thread, null=True, blank=True,
+    thread = models.ForeignKey(
+            Thread, null=True, blank=True,
             on_delete=models.SET_NULL, related_name='posts')
     title = models.CharField(max_length=255)
     creation_date = models.DateTimeField()