diff --git a/.github/PULL_REQUEST_TEMPLATE.MD b/.github/PULL_REQUEST_TEMPLATE.MD new file mode 100644 index 000000000..eb8203925 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.MD @@ -0,0 +1,10 @@ + diff --git a/.gitignore b/.gitignore index f95d164a6..4875ad398 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ venv staticfiles .env db.sqlite3 +getting-started/* \ No newline at end of file diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 70ca30fda..000000000 --- a/Pipfile +++ /dev/null @@ -1,16 +0,0 @@ -[[source]] - -url = "https://pypi.python.org/simple" -verify_ssl = true - - -[packages] - -django = "*" -gunicorn = "*" -django-heroku = "*" - - -[requires] - -python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 397a1c9d2..000000000 --- a/Pipfile.lock +++ /dev/null @@ -1,118 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7843aa61794626156c5dbfa26d6be61df24889c396f04a8dead353d23e2899d6" - }, - "host-environment-markers": { - "implementation_name": "cpython", - "implementation_version": "3.6.3", - "os_name": "posix", - "platform_machine": "x86_64", - "platform_python_implementation": "CPython", - "platform_release": "17.3.0", - "platform_system": "Darwin", - "platform_version": "Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64", - "python_full_version": "3.6.3", - "python_version": "3.6", - "sys_platform": "darwin" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.6" - }, - "sources": [ - { - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "dj-database-url": { - "hashes": [ - "sha256:e16d94c382ea0564c48038fa7fe8d9c890ef1ab1a8ec4cb48e732c124b9482fd", - "sha256:a6832d8445ee9d788c5baa48aef8130bf61fdc442f7d9a548424d25cd85c9f08" - ], - "version": "==0.4.2" - }, - "django": { - "hashes": [ - "sha256:af18618ce3291be5092893d8522fe3919661bf3a1fb60e3858ae74865a4f07c2", - "sha256:9614851d4a7ff8cbd32b73c6076441f377c45a5bbff7e771798fb02c43c31f47" - ], - "version": "==2.0" - }, - "django-heroku": { - "hashes": [ - "sha256:193bacbe644a607642f6b60acd0a382d6abf4a1f7578f8d3eb10659457efe904", - "sha256:af6c723872553b7427121a865eb9fce70d566b9ad26d7defcdcd03a8acea56c8" - ], - "version": "==0.1.0" - }, - "gunicorn": { - "hashes": [ - "sha256:75af03c99389535f218cc596c7de74df4763803f7b63eb09d77e92b3956b36c6", - "sha256:eee1169f0ca667be05db3351a0960765620dad53f53434262ff8901b68a1b622" - ], - "version": "==19.7.1" - }, - "psycopg2": { - "hashes": [ - "sha256:594aa9a095de16614f703d759e10c018bdffeafce2921b8e80a0e8a0ebbc12e5", - "sha256:1cf5d84290c771eeecb734abe2c6c3120e9837eb12f99474141a862b9061ac51", - "sha256:0344b181e1aea37a58c218ccb0f0f771295de9aa25a625ed076e6996c6530f9e", - "sha256:25250867a4cd1510fb755ef9cb38da3065def999d8e92c44e49a39b9b76bc893", - "sha256:317612d5d0ca4a9f7e42afb2add69b10be360784d21ce4ecfbca19f1f5eadf43", - "sha256:9d6266348b15b4a48623bf4d3e50445d8e581da413644f365805b321703d0fac", - "sha256:ddca39cc55877653b5fcf59976d073e3d58c7c406ef54ae8e61ddf8782867182", - "sha256:988d2ec7560d42ef0ac34b3b97aad14c4f068792f00e1524fa1d3749fe4e4b64", - "sha256:7a9c6c62e6e05df5406e9b5235c31c376a22620ef26715a663cee57083b3c2ea", - "sha256:7a75565181e75ba0b9fb174b58172bf6ea9b4331631cfe7bafff03f3641f5d73", - "sha256:94e4128ba1ea56f02522fffac65520091a9de3f5c00da31539e085e13db4771b", - "sha256:92179bd68c2efe72924a99b6745a9172471931fc296f9bfdf9645b75eebd6344", - "sha256:b9358e203168fef7bfe9f430afaed3a2a624717a1d19c7afa7dfcbd76e3cd95c", - "sha256:009e0bc09a57dbef4b601cb8b46a2abad51f5274c8be4bba276ff2884cd4cc53", - "sha256:d3ac07240e2304181ffdb13c099840b5eb555efc7be9344503c0c03aa681de79", - "sha256:40fa5630cd7d237cd93c4d4b64b9e5ed9273d1cfce55241c7f9066f5db70629d", - "sha256:6c2f1a76a9ebd9ecf7825b9e20860139ca502c2bf1beabf6accf6c9e66a7e0c3", - "sha256:37f54452c7787dbdc0a634ca9773362b91709917f0b365ed14b831f03cbd34ba", - "sha256:8f5942a4daf1ffac42109dc4a72f786af4baa4fa702ede1d7c57b4b696c2e7d6", - "sha256:bf708455cd1e9fa96c05126e89a0c59b200d086c7df7bbafc7d9be769e4149a3", - "sha256:82c40ea3ac1555e0462803380609fbe8b26f52620f3d4f8eb480cfd8ceed8a14", - "sha256:207ba4f9125a0a4200691e82d5eee7ea1485708eabe99a07fc7f08696fae62f4", - "sha256:0cd4c848f0e9d805d531e44973c8f48962e20eb7fc0edac3db4f9dbf9ed5ab82", - "sha256:57baf63aeb2965ca4b52613ce78e968b6d2bde700c97f6a7e8c6c236b51ab83e", - "sha256:2954557393cfc9a5c11a5199c7a78cd9c0c793a047552d27b1636da50d013916", - "sha256:7c31dade89634807196a6b20ced831fbd5bec8a21c4e458ea950c9102c3aa96f", - "sha256:1286dd16d0e46d59fa54582725986704a7a3f3d9aca6c5902a7eceb10c60cb7e", - "sha256:697ff63bc5451e0b0db48ad205151123d25683b3754198be7ab5fcb44334e519", - "sha256:fc993c9331d91766d54757bbc70231e29d5ceb2d1ac08b1570feaa0c38ab9582", - "sha256:9d64fed2681552ed642e9c0cc831a9e95ab91de72b47d0cb68b5bf506ba88647", - "sha256:5c3213be557d0468f9df8fe2487eaf2990d9799202c5ff5cb8d394d09fad9b2a" - ], - "version": "==2.7.3.2" - }, - "pytz": { - "hashes": [ - "sha256:80af0f3008046b9975242012a985f04c5df1f01eed4ec1633d56cc47a75a6a48", - "sha256:feb2365914948b8620347784b6b6da356f31c9d03560259070b2f30cff3d469d", - "sha256:59707844a9825589878236ff2f4e0dc9958511b7ffaae94dc615da07d4a68d33", - "sha256:d0ef5ef55ed3d37854320d4926b04a4cb42a2e88f71da9ddfdacfde8e364f027", - "sha256:c41c62827ce9cafacd6f2f7018e4f83a6f1986e87bfd000b8cfbd4ab5da95f1a", - "sha256:8cc90340159b5d7ced6f2ba77694d946fc975b09f1a51d93f3ce3bb399396f94", - "sha256:dd2e4ca6ce3785c8dd342d1853dd9052b19290d5bf66060846e5dc6b8d6667f7", - "sha256:699d18a2a56f19ee5698ab1123bbcc1d269d061996aeb1eda6d89248d3542b82", - "sha256:fae4cffc040921b8a2d60c6cf0b5d662c1190fe54d718271db4eb17d44a185b7" - ], - "version": "==2017.3" - }, - "whitenoise": { - "hashes": [ - "sha256:15f43b2e701821b95c9016cf469d29e2a546cb1c7dead584ba82c36f843995cf", - "sha256:9d81515f2b5b27051910996e1e860b1332e354d9e7bcf30c98f21dcb6713e0dd" - ], - "version": "==3.3.1" - } - }, - "develop": {} -} diff --git a/Procfile b/Procfile index b6f89307b..47a27c07f 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: gunicorn gettingstarted.wsgi +web: gunicorn gettingstarted.wsgi --log-file - diff --git a/README.md b/README.md index 23ff5a077..8cbdb7f82 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,14 @@ This application supports the [Getting Started with Python on Heroku](https://de ## Running Locally -Make sure you have Python [installed properly](http://install.python-guide.org). Also, install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) and [Postgres](https://devcenter.heroku.com/articles/heroku-postgresql#local-setup). +Make sure you have Python 3.7 [installed locally](http://install.python-guide.org). To push to Heroku, you'll need to install the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli), as well as [Postgres](https://devcenter.heroku.com/articles/heroku-postgresql#local-setup). ```sh -$ git clone git@github.com:heroku/python-getting-started.git +$ git clone https://github.com/heroku/python-getting-started.git $ cd python-getting-started -$ pipenv install +$ python3 -m venv getting-started +$ pip install -r requirements.txt $ createdb python_getting_started diff --git a/gettingstarted/settings.py b/gettingstarted/settings.py index fcb04e27c..9ea552a0c 100644 --- a/gettingstarted/settings.py +++ b/gettingstarted/settings.py @@ -22,7 +22,7 @@ # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'CHANGE_ME!!!! (P.S. the SECRET_KEY environment variable will be used, if set, instead).' +SECRET_KEY = "CHANGE_ME!!!! (P.S. the SECRET_KEY environment variable will be used, if set, instead)." # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -33,78 +33,75 @@ # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'django.contrib.gis', - 'hello' + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "hello", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'gettingstarted.urls' +ROOT_URLCONF = "gettingstarted.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ] }, - }, + } ] -WSGI_APPLICATION = 'gettingstarted.wsgi.application' +WSGI_APPLICATION = "gettingstarted.wsgi.application" # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases -import dj_database_url -DATABASES = {'default': dj_database_url.config(engine='django.contrib.gis.db.backends.postgis')} +DATABASES = { + "default": { + "ENGINE" : "django.db.backends.sqlite3", + "NAME": os.path.join(BASE_DIR, "db.sqlite3") + } +} # Password validation # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ] # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -116,6 +113,7 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ -STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') +STATIC_URL = "/static/" django_heroku.settings(locals()) diff --git a/gettingstarted/urls.py b/gettingstarted/urls.py index 36492ed3c..13b759582 100644 --- a/gettingstarted/urls.py +++ b/gettingstarted/urls.py @@ -1,17 +1,21 @@ -from django.conf.urls import include, url -from django.urls import path +from django.urls import path, include from django.contrib import admin + admin.autodiscover() import hello.views -# Examples: -# url(r'^$', 'gettingstarted.views.home', name='home'), -# url(r'^blog/', include('blog.urls')), +# To add a new path, first import the app: +# import blog +# +# Then add the new path: +# path('blog/', blog.urls, name="blog") +# +# Learn more here: https://docs.djangoproject.com/en/2.1/topics/http/urls/ urlpatterns = [ - url(r'^$', hello.views.index, name='index'), - url(r'^db', hello.views.db, name='db'), - path('admin/', admin.site.urls), + path("", hello.views.index, name="index"), + path("db/", hello.views.db, name="db"), + path("admin/", admin.site.urls), ] diff --git a/gettingstarted/wsgi.py b/gettingstarted/wsgi.py index feb0af46f..3c528d7ce 100644 --- a/gettingstarted/wsgi.py +++ b/gettingstarted/wsgi.py @@ -4,10 +4,11 @@ It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see -https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ +https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ """ import os + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gettingstarted.settings") from django.core.wsgi import get_wsgi_application diff --git a/hello/models.py b/hello/models.py index ec0cc93cb..8229092ef 100644 --- a/hello/models.py +++ b/hello/models.py @@ -1,11 +1,5 @@ -from django.contrib.gis.db import models +from django.db import models # Create your models here. class Greeting(models.Model): - when = models.DateTimeField('date created', auto_now_add=True) - - -class TestGeo(models.Model): - geometry = models.GeometryField() - point = models.PointField() - mpoly = models.MultiPolygonField() + when = models.DateTimeField("date created", auto_now_add=True) diff --git a/hello/tests.py b/hello/tests.py index 1d69113fe..9b06366a5 100644 --- a/hello/tests.py +++ b/hello/tests.py @@ -3,6 +3,7 @@ from .views import index + class SimpleTest(TestCase): def setUp(self): # Every test needs access to the request factory. @@ -10,9 +11,9 @@ def setUp(self): def test_details(self): # Create an instance of a GET request. - request = self.factory.get('/') + request = self.factory.get("/") request.user = AnonymousUser() # Test my_view() as if it were deployed at /customer/details response = index(request) - self.assertEqual(response.status_code, 200) \ No newline at end of file + self.assertEqual(response.status_code, 200) diff --git a/hello/views.py b/hello/views.py index db2611ac0..c2480724b 100644 --- a/hello/views.py +++ b/hello/views.py @@ -1,12 +1,12 @@ from django.shortcuts import render from django.http import HttpResponse -from .models import Greeting, TestGeo +from .models import Greeting # Create your views here. def index(request): # return HttpResponse('Hello from Python!') - return render(request, 'index.html') + return render(request, "index.html") def db(request): @@ -16,5 +16,4 @@ def db(request): greetings = Greeting.objects.all() - return render(request, 'db.html', {'greetings': greetings}) - + return render(request, "db.html", {"greetings": greetings}) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..4af6a3765 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +django +gunicorn +django-heroku \ No newline at end of file diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 000000000..b16fb5e0e --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.7.0 \ No newline at end of file