From 6b962fa3e27228624aa8430bbf84e577acd4afab Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Mon, 19 Dec 2016 10:32:40 +0100 Subject: [PATCH] Django 1.8+ compatibility Update odsreg so that it runs with Django 1.8: - Move base files under an odsreg module, update .gitignore - Update module paths - Update manage.py to Django 1.8 version - Update instructions in README.rst - Remove 'null has no effect on ManyToManyField' warning Update odsreg so that it runs with Django 1.9: - Update management command arg handling - Use url instead of patterns in urls.py - Move from TEMPLATE_* variables to TEMPLATES Co-Authored-By: Tom Fifield Change-Id: Ic18bddd29053ca0187889bb8a371048b2ad3fdb9 --- .gitignore | 4 +- README.rst | 13 +++--- cfp/admin.py | 2 +- cfp/forms.py | 2 +- cfp/management/commands/loadevent.py | 10 +++-- cfp/middleware.py | 2 +- cfp/models.py | 2 +- cfp/urls.py | 24 ++++++----- cfp/views.py | 8 ++-- manage.py | 33 ++++----------- __init__.py => odsreg/__init__.py | 0 .../local_settings.py.sample | 2 +- settings.py => odsreg/settings.py | 42 ++++++++++++------- urls.py => odsreg/urls.py | 17 ++++---- scheduling/admin.py | 2 +- scheduling/forms.py | 2 +- scheduling/models.py | 4 +- scheduling/urls.py | 17 ++++---- scheduling/views.py | 14 +++---- 19 files changed, 101 insertions(+), 99 deletions(-) rename __init__.py => odsreg/__init__.py (100%) rename local_settings.py.sample => odsreg/local_settings.py.sample (98%) rename settings.py => odsreg/settings.py (73%) rename urls.py => odsreg/urls.py (70%) diff --git a/.gitignore b/.gitignore index 2a6023f..bf25d81 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,7 @@ *.sqlite *.db *~ -local_settings.py +.venv +odsreg/local_settings.py +event.json slots.json diff --git a/README.rst b/README.rst index 4997f2d..6b5691e 100644 --- a/README.rst +++ b/README.rst @@ -18,14 +18,14 @@ Prerequisites ------------- You'll need the following Python modules installed: - - django (1.4+) + - django (1.8+) - python-django-auth-openid OR If you are using pip with or without a venv, you can use the following commands instead: - - pip install django==1.4 + - pip install django - pip install python-openid - pip install django-openid-auth @@ -33,11 +33,14 @@ you can use the following commands instead: Configuration and Usage ----------------------- -Copy local_settings.py.sample to local_settings.py and change -settings there. +Copy odsreg/local_settings.py.sample to odsreg/local_settings.py and change +settings there. In particular you should set DEBUG=True or ALLOWED_HOSTS. Create empty database: -./manage.py syncdb +./manage.py migrate + +Create a superuser: +./manage.py createsuperuser Copy event.json.sample to event.json and edit the file to match the event and topics you want to have. Then run: diff --git a/cfp/admin.py b/cfp/admin.py index dd8b207..b86de6a 100644 --- a/cfp/admin.py +++ b/cfp/admin.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from odsreg.cfp.models import Topic, Proposal, Event, Comment +from cfp.models import Topic, Proposal, Event, Comment from django.contrib import admin diff --git a/cfp/forms.py b/cfp/forms.py index 940c6bf..7f251de 100644 --- a/cfp/forms.py +++ b/cfp/forms.py @@ -15,7 +15,7 @@ from django.forms import ModelForm, CharField, Textarea -from odsreg.cfp.models import Comment, Proposal +from cfp.models import Comment, Proposal class CommentForm(ModelForm): diff --git a/cfp/management/commands/loadevent.py b/cfp/management/commands/loadevent.py index 189e4bd..8065d8d 100644 --- a/cfp/management/commands/loadevent.py +++ b/cfp/management/commands/loadevent.py @@ -16,20 +16,22 @@ import json from django.core.management.base import BaseCommand, CommandError -from odsreg.cfp.models import Event, Topic +from cfp.models import Event, Topic class Command(BaseCommand): args = '' help = 'Create topics from JSON description' - def handle(self, *args, **options): + def add_arguments(self, parser): + parser.add_argument('descriptive_json') - if len(args) != 1: + def handle(self, *args, **options): + if 'descriptive_json' not in options.keys(): raise CommandError('Incorrect arguments') try: - with open(args[0]) as f: + with open(options['descriptive_json']) as f: data = json.load(f) except ValueError as exc: raise CommandError("Malformed JSON: %s" % exc.message) diff --git a/cfp/middleware.py b/cfp/middleware.py index 8086671..015f9f8 100644 --- a/cfp/middleware.py +++ b/cfp/middleware.py @@ -15,7 +15,7 @@ from django.shortcuts import render -from odsreg.cfp.models import Event +from cfp.models import Event class EventMiddleware(): diff --git a/cfp/models.py b/cfp/models.py index 0d09ba3..1325359 100644 --- a/cfp/models.py +++ b/cfp/models.py @@ -16,7 +16,7 @@ from django.db import models from django.contrib.auth.models import User -from odsreg.cfp.utils import validate_bp +from cfp.utils import validate_bp class Event(models.Model): diff --git a/cfp/urls.py b/cfp/urls.py index 233af58..fd8bcc6 100644 --- a/cfp/urls.py +++ b/cfp/urls.py @@ -13,16 +13,18 @@ # License for the specific language governing permissions and limitations # under the License. -from django.conf.urls.defaults import * +from django.conf.urls import url + +from cfp import views -urlpatterns = patterns('odsreg.cfp.views', - (r'^details/(\d+)$', 'details'), - (r'^edit/(\d+)$', 'edit'), - (r'^create$', 'create'), - (r'^review/(\d+)$', 'review'), - (r'^switch/(\d+)$', 'switch'), - (r'^delete/(\d+)$', 'delete'), - (r'^topic/(\d+)$', 'topiclist'), - (r'^topicstatus$', 'topicstatus'), -) +urlpatterns = [ + url(r'^details/(\d+)$', views.details), + url(r'^edit/(\d+)$', views.edit), + url(r'^create$', views.create), + url(r'^review/(\d+)$', views.review), + url(r'^switch/(\d+)$', views.switch), + url(r'^delete/(\d+)$', views.delete), + url(r'^topic/(\d+)$', views.topiclist), + url(r'^topicstatus$', views.topicstatus), +] diff --git a/cfp/views.py b/cfp/views.py index 7cbad8b..d75a922 100644 --- a/cfp/views.py +++ b/cfp/views.py @@ -22,10 +22,10 @@ from django.http import HttpResponseRedirect, HttpResponseForbidden from django.template.response import TemplateResponse from django.utils.encoding import smart_str -from odsreg.cfp.models import Proposal, Topic, Comment -from odsreg.cfp.forms import ProposalForm, ProposalEditForm, CommentForm -from odsreg.cfp.forms import ProposalReviewForm, ProposalSwitchForm -from odsreg.cfp.utils import linkify, is_editable, topiclead +from cfp.models import Proposal, Topic, Comment +from cfp.forms import ProposalForm, ProposalEditForm, CommentForm +from cfp.forms import ProposalReviewForm, ProposalSwitchForm +from cfp.utils import linkify, is_editable, topiclead @login_required diff --git a/manage.py b/manage.py index 303b70a..d903882 100755 --- a/manage.py +++ b/manage.py @@ -1,29 +1,10 @@ #!/usr/bin/env python - -# Copyright 2011 Thierry Carrez -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from django.core.management import execute_manager - - -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py'\n") - sys.exit(1) +import os +import sys if __name__ == "__main__": - execute_manager(settings) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "odsreg.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/__init__.py b/odsreg/__init__.py similarity index 100% rename from __init__.py rename to odsreg/__init__.py diff --git a/local_settings.py.sample b/odsreg/local_settings.py.sample similarity index 98% rename from local_settings.py.sample rename to odsreg/local_settings.py.sample index b0fc797..b81c6e6 100644 --- a/local_settings.py.sample +++ b/odsreg/local_settings.py.sample @@ -28,8 +28,8 @@ DATABASES = { SECRET_KEY = 'generateRandomOneHere' # Run in production +ALLOWED_HOSTS = [] DEBUG = False -TEMPLATE_DEBUG = DEBUG #OPENID_USE_AS_ADMIN_LOGIN = True # Emails diff --git a/settings.py b/odsreg/settings.py similarity index 73% rename from settings.py rename to odsreg/settings.py index fca91b4..8357f99 100644 --- a/settings.py +++ b/odsreg/settings.py @@ -21,7 +21,6 @@ import os PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) DEBUG = True -TEMPLATE_DEBUG = DEBUG SERVE_STATIC = True @@ -42,18 +41,28 @@ STATIC_URL = '/media/' SECRET_KEY = 'changemeInLocalSettings' # List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -) - -TEMPLATE_CONTEXT_PROCESSORS = ( - "django.contrib.auth.context_processors.auth", - "django.core.context_processors.debug", - "django.core.context_processors.i18n", - "django.core.context_processors.media", - "django.core.context_processors.request", -) +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + # insert your TEMPLATE_DIRS here + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this + # list if you haven't customized them: + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', @@ -61,7 +70,7 @@ MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', - 'odsreg.cfp.middleware.EventMiddleware', + 'cfp.middleware.EventMiddleware', ) ROOT_URLCONF = 'odsreg.urls' @@ -74,8 +83,8 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'django_openid_auth', 'django.contrib.admin', - 'odsreg.cfp', - 'odsreg.scheduling', + 'cfp', + 'scheduling', ] AUTHENTICATION_BACKENDS = ( @@ -86,6 +95,7 @@ AUTHENTICATION_BACKENDS = ( # Should users be created when new OpenIDs are used to log in? OPENID_CREATE_USERS = True OPENID_STRICT_USERNAMES = True +SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' # Can we reuse existing users? OPENID_REUSE_USERS = True diff --git a/urls.py b/odsreg/urls.py similarity index 70% rename from urls.py rename to odsreg/urls.py index eff48f9..93e6f09 100644 --- a/urls.py +++ b/odsreg/urls.py @@ -13,17 +13,18 @@ # License for the specific language governing permissions and limitations # under the License. -from django.conf.urls.defaults import * +from django.conf.urls import include, url from django.contrib import admin +from cfp import views admin.autodiscover() -urlpatterns = patterns('', - (r'^openid/', include('django_openid_auth.urls')), - (r'^$', 'odsreg.cfp.views.list'), - (r'^cfp/', include('odsreg.cfp.urls')), - (r'^scheduling/', include('odsreg.scheduling.urls')), +urlpatterns = [ + url(r'^openid/', include('django_openid_auth.urls')), + url(r'^$', views.list), + url(r'^cfp/', include('cfp.urls')), + url(r'^scheduling/', include('scheduling.urls')), url(r'^admin/', include(admin.site.urls)), - (r'^logout$', 'odsreg.cfp.views.dologout'), -) + url(r'^logout$', views.dologout), +] diff --git a/scheduling/admin.py b/scheduling/admin.py index 8a93fd5..76d867b 100644 --- a/scheduling/admin.py +++ b/scheduling/admin.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from odsreg.scheduling.models import Slot, Room +from scheduling.models import Slot, Room from django.contrib import admin diff --git a/scheduling/forms.py b/scheduling/forms.py index d2d33f3..3ea35ea 100644 --- a/scheduling/forms.py +++ b/scheduling/forms.py @@ -15,7 +15,7 @@ from django.forms import ModelForm -from odsreg.scheduling.models import Slot +from scheduling.models import Slot class SlotForm(ModelForm): diff --git a/scheduling/models.py b/scheduling/models.py index 50b6b8a..06bff9a 100644 --- a/scheduling/models.py +++ b/scheduling/models.py @@ -15,7 +15,7 @@ from django.db import models -from odsreg.cfp.models import Proposal, Topic +from cfp.models import Proposal, Topic class Room(models.Model): @@ -33,7 +33,7 @@ class Slot(models.Model): start_time = models.CharField(max_length=16) room = models.ForeignKey(Room) topic = models.ForeignKey(Topic) - proposals = models.ManyToManyField(Proposal, blank=True, null=True) + proposals = models.ManyToManyField(Proposal, blank=True) title = models.CharField(max_length=60, blank=True, verbose_name="Override title with", help_text="Default title is the title of the first proposal. You can" diff --git a/scheduling/urls.py b/scheduling/urls.py index 9146b8b..7a670d7 100644 --- a/scheduling/urls.py +++ b/scheduling/urls.py @@ -13,13 +13,14 @@ # License for the specific language governing permissions and limitations # under the License. -from django.conf.urls.defaults import * +from django.conf.urls import url +from scheduling import views -urlpatterns = patterns('odsreg.scheduling.views', - (r'^(\d+)$', 'scheduling'), - (r'^edit/(\d+)$', 'edit'), - (r'^swap/(\d+)$', 'swap'), - (r'^publish/(\d+)$', 'publish'), - (r'^graph/(\d+)$', 'graph'), -) +urlpatterns = [ + url(r'^(\d+)$', views.scheduling), + url(r'^edit/(\d+)$', views.edit), + url(r'^swap/(\d+)$', views.swap), + url(r'^publish/(\d+)$', views.publish), + url(r'^graph/(\d+)$', views.graph), +] diff --git a/scheduling/views.py b/scheduling/views.py index 7ee8277..39985c1 100644 --- a/scheduling/views.py +++ b/scheduling/views.py @@ -19,13 +19,13 @@ import urllib2 from django.http import HttpResponseRedirect, HttpResponseForbidden from django.template.response import TemplateResponse from django.utils.encoding import smart_str -from odsreg.cfp.models import Proposal, Topic, Event -from odsreg.cfp.utils import topiclead -from odsreg.scheduling.forms import SlotForm -from odsreg.scheduling.models import Slot -from odsreg.scheduling.utils import combined_id, combined_title -from odsreg.scheduling.utils import combined_description, full_description -from odsreg.scheduling.utils import htmlize, end_time +from cfp.models import Proposal, Topic, Event +from cfp.utils import topiclead +from scheduling.forms import SlotForm +from scheduling.models import Slot +from scheduling.utils import combined_id, combined_title +from scheduling.utils import combined_description, full_description +from scheduling.utils import htmlize, end_time def scheduling(request, topicid):