diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..a062c423e8ed260ffa4e6f634529fc1416eb9fb9 Binary files /dev/null and b/db.sqlite3 differ diff --git a/imagedb/__init__.py b/imagedb/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/imagedb/admin.py b/imagedb/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..1fb5e8fd01b802cead3e2632e7f558006195e779 --- /dev/null +++ b/imagedb/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin + +from .models import(Instrument, NispRawFrame, NispDetector, Astrometry) + +# Register your models here. +admin.site.register(Instrument) +admin.site.register(NispRawFrame) +admin.site.register(NispDetector) +admin.site.register(Astrometry) diff --git a/imagedb/apps.py b/imagedb/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..044a53ae7cd9d67c5d339b9b82e209ba4b80c976 --- /dev/null +++ b/imagedb/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ImagedbConfig(AppConfig): + name = 'imagedb' diff --git a/imagedb/models.py b/imagedb/models.py new file mode 100644 index 0000000000000000000000000000000000000000..f338f91a6dcf932464ca41415a1c6696c6a79480 --- /dev/null +++ b/imagedb/models.py @@ -0,0 +1,184 @@ + +from django.db import models +from composite_field import CompositeField + +# Create your models here. + + +IMAGE_CATEGORY = ( + 'SCIENCE', + 'CALIBRATION', + 'SIMULATION' +) + +IMAGE_FIRST_GROUP = ( + 'OBJECT', + 'STD', + 'BIAS', + 'DARK', + 'FLAT', + 'LINEARITY', + 'OTHER' +) + + +IMAGE_SECOND_GROUP = ( + 'SKY', + 'LAMP', + 'DOME', + 'OTHER' +) + +class ImageType(CompositeField): + + category = models.CharField( + max_length=20, + choices=[(d, d) for d in IMAGE_CATEGORY] + ) + + firstType = models.CharField( + max_length=20, + choices=[(d,d) for d in IMAGE_FIRST_GROUP] + ) + + secondType = models.CharField( + max_length=20, + choices=[(d,d) for d in IMAGE_SECOND_GROUP] + ) + + + +class ImageBaseFrame(models.Model): + exposureTime = models.FloatField() + imgNumber = models.PositiveSmallIntegerField() + naxis1 = models.PositiveIntegerField() + naxis2 = models.PositiveIntegerField() + imageType = ImageType() + + class Meta: + abstract = True + + +class Instrument(models.Model): + instrumentName = models.CharField(max_length=100) + telescopeName = models.CharField(max_length=100) + + +class Pointing(CompositeField): + rightAscension = models.FloatField() + declination = models.FloatField() + pointingAngle = models.FloatField() + + +class ImageSpaceFrame(ImageBaseFrame): + observationDateTime = models.DateTimeField() + instrument = models.ForeignKey(Instrument, on_delete=models.CASCADE) + commandedPointing = Pointing() + + class Meta: + abstract = True + + +NISP_DETECTOR_ID = ( + '11','12','13','14', + '21','22','23','24', + '31','32','33','34', + '41','42','43','44' +) + + +class NispDetector(models.Model): + detectorId = models.CharField( + max_length=2, + choices = [(d,d) for d in NISP_DETECTOR_ID] + ) + gain = models.FloatField() + readoutNoise = models.FloatField() + rawFrame = models.ForeignKey('NispRawFrame', + related_name='detectors', + on_delete=models.CASCADE) + + +WCS_COORDINATE_TYPE = ( + 'RA', + 'DEC', + 'GLON', + 'GLAT', + 'ELON', + 'ELAT' +) + +WCS_PROJECTION_TYPE = ( + 'LOG', + 'TAN', + 'SIN' +) + + +class CtypeWcs(CompositeField): + coordinateType = models.CharField( + max_length=4, + choices = [(d,d) for d in WCS_COORDINATE_TYPE] + ) + projectionType = models.CharField( + max_length=3, + choices = [(d,d) for d in WCS_PROJECTION_TYPE] + ) + + +class Astrometry(models.Model): + ctpye1 = CtypeWcs() + ctype2 = CtypeWcs() + crval1 = models.FloatField() + crval2 = models.FloatField() + crpix1 = models.FloatField() + crpix2 = models.FloatField() + cd1_1 = models.FloatField() + cd1_2 = models.FloatField() + cd2_1 = models.FloatField() + cd2_2 = models.FloatField() + detector = models.OneToOneField(NispDetector, + related_name='astrometry', + blank=True, + null=True, + on_delete=models.CASCADE) + + +NISP_FILTER_WHEEL = ( + 'Y', + 'J', + 'H', + 'OPEN', + 'CLOSE' +) + +NISP_GRISM_WHEEL = ( + 'BLUE0', + 'RED0', + 'RED90', + 'RED180' + 'OPEN' + 'CLOSE' +) + +class NispRawFrame(ImageSpaceFrame): + filterWheelPosition = models.CharField( + max_length=10, + choices = [(d,d) for d in NISP_FILTER_WHEEL] + ) + + grismWheelPosition = models.CharField( + max_length=10, + choices = [(d,d) for d in NISP_GRISM_WHEEL] + ) + + + + + + + + + + + diff --git a/imagedb/serializers.py b/imagedb/serializers.py new file mode 100644 index 0000000000000000000000000000000000000000..2a38507c621872d6bf7e14fd5a9508ea9a713ef5 --- /dev/null +++ b/imagedb/serializers.py @@ -0,0 +1,33 @@ + +from composite_field.rest_framework_support import CompositeFieldSerializer +from rest_framework import serializers + + +from imagedb.models import Instrument, NispDetector, NispRawFrame + +class InstrumentSerializer(serializers.ModelSerializer): + class Meta: + model = Instrument + fields = '__all__' + +class NispDetectorSerializer(serializers.ModelSerializer): + class Meta: + model = NispDetector + exclude = ('rawFrame',) + +class NispRawFrameSerializer(serializers.ModelSerializer): + detectors = NispDetectorSerializer(many = True, read_only = True) + commandedPointing = CompositeFieldSerializer() + imageType = CompositeFieldSerializer() + + class Meta: + model = NispRawFrame + exclude = ('commandedPointing_rightAscension', + 'commandedPointing_declination', + 'commandedPointing_pointingAngle', + 'imageType_category', + 'imageType_firstType', + 'imageType_secondType') + depth = 2 + + diff --git a/imagedb/tests.py b/imagedb/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6 --- /dev/null +++ b/imagedb/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/imagedb/urls.py b/imagedb/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..50f0483c586419f59ad16d3f98bb5f6337540b2d --- /dev/null +++ b/imagedb/urls.py @@ -0,0 +1,13 @@ +from django.conf.urls import url, include +from rest_framework.routers import DefaultRouter + +from imagedb import views + +router = DefaultRouter() +router.register(r'instruments', views.InstrumentViewSet) +router.register(r'nisprawframes', views.NispRawFrameViewSet) +router.register(r'nispdetectors', views.NispDetectorViewSet) + +urlpatterns = [ + url(r'^', include(router.urls)) +] diff --git a/imagedb/views.py b/imagedb/views.py new file mode 100644 index 0000000000000000000000000000000000000000..b2009c8343acbb3118e263d771ed1f8add99028c --- /dev/null +++ b/imagedb/views.py @@ -0,0 +1,30 @@ + +from rest_framework import viewsets +from imagedb.serializers import InstrumentSerializer, NispDetectorSerializer, NispRawFrameSerializer +from imagedb.models import Instrument, NispDetector, NispRawFrame +from url_filter.filtersets import ModelFilterSet + + +class InstrumentViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Instrument.objects.all() + serializer_class = InstrumentSerializer + +class NispDetectorViewSet(viewsets.ReadOnlyModelViewSet): + queryset = NispDetector.objects.all() + serializer_class = NispDetectorSerializer + + + +class NispRawFrameFilterSet(ModelFilterSet): + class Meta: + model = NispRawFrame + fields = ['id','imageType_category'] + +class NispRawFrameViewSet(viewsets.ReadOnlyModelViewSet): + queryset = NispRawFrame.objects.all() + serializer_class = NispRawFrameSerializer + filter_class = NispRawFrameFilterSet + + + + diff --git a/imagedb_objects.ipynb b/imagedb_objects.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..f4600b2b746f5c7fd9a65fb028fbcdfdd0c25089 --- /dev/null +++ b/imagedb_objects.ipynb @@ -0,0 +1,347 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from imagedb.models import Instrument\n", + "\n", + "instrument = Instrument.objects.get(instrumentName='NISP')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NISP\n" + ] + } + ], + "source": [ + "print(instrument.instrumentName)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from imagedb.models import ImageType, Pointing, NispDetector, NispRawFrame\n", + "\n", + "from datetime import datetime\n", + " \n", + "\n", + "image = NispRawFrame(exposureTime = 105,\n", + " imgNumber = 16,\n", + " naxis1 = 2040,\n", + " naxis2 = 2040,\n", + " imageType = {'category':'SCIENCE', \n", + " 'firstType':'OBJECT', \n", + " 'secondType':'STD'},\n", + " observationDateTime = datetime.strptime(\"2025-06-21T18:27:23.000001\", \n", + " \"%Y-%m-%dT%H:%M:%S.%f\"),\n", + " instrument = instrument,\n", + " commandedPointing = {'rightAscension':8.48223045516,\n", + " 'declination':8.48223045516,\n", + " 'pointingAngle':64.8793517547},\n", + " filterWheelPosition = \"Y\",\n", + " grismWheelPosition = \"OPEN\"\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Pointing(rightAscension=8.48223045516, declination=8.48223045516, pointingAngle=64.8793517547)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "image.commandedPointing" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8.48223045516" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "image.commandedPointing.rightAscension" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "image = NispRawFrame.objects.filter(commandedPointing_rightAscension__lte=8.48223045516)[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "d = NispDetector(detectorId = \"11\", gain = 1.0, readoutNoise = 0.0, rawFrame = image)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'category': 'SCIENCE', 'firstType': 'OBJECT', 'secondType': 'STD'}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "it = image.imageType\n", + "repr(it)\n", + "it.to_dict()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "from imagedb.serializers import NispRawFrameSerializer\n", + "\n", + "s = NispRawFrameSerializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "OrderedDict([('id', IntegerField(label='ID', read_only=True)),\n", + " ('detectors', NispDetectorSerializer(many=True, read_only=True):\n", + " id = IntegerField(label='ID', read_only=True)\n", + " detectorId = ChoiceField(choices=[('11', '11'), ('12', '12'), ('13', '13'), ('14', '14'), ('21', '21'), ('22', '22'), ('23', '23'), ('24', '24'), ('31', '31'), ('32', '32'), ('33', '33'), ('34', '34'), ('41', '41'), ('42', '42'), ('43', '43'), ('44', '44')], label='DetectorId')\n", + " gain = FloatField()\n", + " readoutNoise = FloatField(label='ReadoutNoise')),\n", + " ('exposureTime', FloatField(label='ExposureTime')),\n", + " ('imgNumber', IntegerField(label='ImgNumber')),\n", + " ('naxis1', IntegerField()),\n", + " ('naxis2', IntegerField()),\n", + " ('imageType_category',\n", + " ChoiceField(choices=[('SCIENCE', 'SCIENCE'), ('CALIBRATION', 'CALIBRATION'), ('SIMULATION', 'SIMULATION')], label='ImageType category')),\n", + " ('imageType_firstType',\n", + " ChoiceField(choices=[('OBJECT', 'OBJECT'), ('STD', 'STD'), ('BIAS', 'BIAS'), ('DARK', 'DARK'), ('FLAT', 'FLAT'), ('LINEARITY', 'LINEARITY'), ('OTHER', 'OTHER')], label='ImageType firstType')),\n", + " ('imageType_secondType',\n", + " ChoiceField(choices=[('SKY', 'SKY'), ('LAMP', 'LAMP'), ('DOME', 'DOME'), ('OTHER', 'OTHER')], label='ImageType secondType')),\n", + " ('observationDateTime',\n", + " DateTimeField(label='ObservationDateTime')),\n", + " ('commandedPointing_rightAscension',\n", + " FloatField(label='CommandedPointing rightAscension')),\n", + " ('commandedPointing_declination',\n", + " FloatField(label='CommandedPointing declination')),\n", + " ('commandedPointing_pointingAngle',\n", + " FloatField(label='CommandedPointing pointingAngle')),\n", + " ('filterWheelPosition',\n", + " ChoiceField(choices=[('Y', 'Y'), ('J', 'J'), ('H', 'H'), ('OPEN', 'OPEN'), ('CLOSE', 'CLOSE')], label='FilterWheelPosition')),\n", + " ('grismWheelPosition',\n", + " ChoiceField(choices=[('BLUE0', 'BLUE0'), ('RED0', 'RED0'), ('RED90', 'RED90'), ('RED180OPENCLOSE', 'RED180OPENCLOSE')], label='GrismWheelPosition')),\n", + " ('instrument', NestedSerializer(read_only=True):\n", + " id = IntegerField(label='ID', read_only=True)\n", + " instrumentName = CharField(label='InstrumentName', max_length=100)\n", + " telescopeName = CharField(label='TelescopeName', max_length=100))])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s.get_fields()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from composite_field.rest_framework_support import CompositeFieldSerializer\n", + "\n", + "c = CompositeFieldSerializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'category': 'SCIENCE', 'firstType': 'OBJECT', 'secondType': 'STD'}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "c.to_representation(it)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "m = NispRawFrameSerializer.Meta.model" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m._meta.concrete_model._meta.fields[15].serialize" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "imagedb.models.Pointing" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(p)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "from composite_field import CompositeField" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "isinstance(p, CompositeField)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Django Shell-Plus", + "language": "python", + "name": "django_extensions" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/manage.py b/manage.py new file mode 100755 index 0000000000000000000000000000000000000000..dedc04fdf5f5dd7e386ce43cab358c20c719947d --- /dev/null +++ b/manage.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == '__main__': + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_example.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) diff --git a/orm_example/__init__.py b/orm_example/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/orm_example/settings.py b/orm_example/settings.py new file mode 100644 index 0000000000000000000000000000000000000000..c651d61c07f8e7dbba34a9a3e2e716f1efbed291 --- /dev/null +++ b/orm_example/settings.py @@ -0,0 +1,130 @@ +""" +Django settings for orm_example project. + +Generated by 'django-admin startproject' using Django 2.1.1. + +For more information on this file, see +https://docs.djangoproject.com/en/2.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.1/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '5yu24^zybby@-q_x%ry-nit^!%o8oc2oxmos7d3_d@hf(+qo5k' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django_extensions', + 'imagedb', + 'rest_framework', + 'url_filter', +] + +REST_FRAMEWORK = { + 'DEFAULT_FILTER_BACKENDS': [ + 'url_filter.integrations.drf.DjangoFilterBackend', + ] +} + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'orm_example.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'orm_example.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.1/howto/static-files/ + +STATIC_URL = '/static/' diff --git a/orm_example/urls.py b/orm_example/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..e68289f7c7e80167bdf4d2853f0c48310ee5e714 --- /dev/null +++ b/orm_example/urls.py @@ -0,0 +1,22 @@ +"""orm_example URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('imagedb/', include('imagedb.urls')), + path('admin/', admin.site.urls), +] diff --git a/orm_example/wsgi.py b/orm_example/wsgi.py new file mode 100644 index 0000000000000000000000000000000000000000..43f817efc76d695df6541a74cea47952ba249e77 --- /dev/null +++ b/orm_example/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for orm_example project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_example.settings') + +application = get_wsgi_application()