Skip to content

Commit

Permalink
Changed project structure for Django library upgrade.
Browse files Browse the repository at this point in the history
Changed settings file setup, now instead of environment variables uses a json file with all the setting data.
Moved the search facet model to the webtsainterface application.
Created a new model on the webtsainterface application to provide the list of Data Series (from the webtsaservices application) field names.
Created a custom api for the the new Data Series model.
Added new and improved admin for search facets.
Created data migrations for the required and default facets.
  • Loading branch information
jcaraballo17 committed Jul 30, 2015
1 parent b7f8ef3 commit ec6615f
Show file tree
Hide file tree
Showing 25 changed files with 553 additions and 150 deletions.
11 changes: 6 additions & 5 deletions .gitignore
@@ -1,16 +1,12 @@
# Python compiled sources and objects
*.py[cod]

# C extensions
*.so

# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
Expand All @@ -34,4 +30,9 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject

# PyCharm
.idea

# Settings data file
src/WEBTSA/settings/settings.json
14 changes: 8 additions & 6 deletions requirements.txt
@@ -1,7 +1,9 @@
Django==1.6.5
django-pyodbc==0.2.4
django-tastypie==0.11.0
pyodbc==3.0.7
python-dateutil==2.2
Django==1.8.3
django-pyodbc-azure==1.8.3.0
django-select2-forms==1.1.18
django-tastypie==0.12.2
pyodbc==3.0.10
python-dateutil==2.4.2
python-mimeparse==0.1.4
six==1.6.1
pytz==2015.4
six==1.9.0
Binary file removed src/Internal
Binary file not shown.
10 changes: 10 additions & 0 deletions src/WEBTSA/db_routers.py
@@ -0,0 +1,10 @@
class DataSeriesRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label == 'webtsaservices':
return 'tsa'
return 'default'

def db_for_write(self, model, **hints):
if model._meta.app_label == 'webtsaservices':
return 'tsa'
return 'default'
80 changes: 53 additions & 27 deletions src/WEBTSA/settings/base.py
@@ -1,34 +1,46 @@
"""
Django settings for WEBTSA project.
To setup the settings json file:
1. rename settings_template.json to settings.json
2. write all the necessary data in it
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import json

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

try:
SECRET_KEY = os.environ['TSA_SECRET_KEY']
DATABASE_HOST = os.environ['TSA_DATABASE_HOST']
DATABASE_USER = os.environ['TSA_DATABASE_USER']
DATABASE_PASSWORD = os.environ['TSA_DATABASE_PASSWORD']
except KeyError:
print "Please set the required environment variables TSA_SECRET_KEY, TSA_DATABASE_HOST, " \
"TSA_DATABASE_USER, TSA_DATABASE_PASSWORD"
exit(True)
with open(os.path.join(BASE_DIR, 'settings', 'settings.json')) as data_file:
data = json.load(data_file)
except IOError:
print("You need to setup the settings data file (see instructions in base.py file.)")


SECRET_KEY = data["secret_key"]

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []

TASTYPIE_DEFAULT_FORMATS = ['json']

# Application definition

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_pyodbc',
'select2',
'tastypie',
'webtsaservices',
'webtsainterface'
Expand All @@ -45,29 +57,41 @@

ROOT_URLCONF = 'WEBTSA.urls'

WSGI_APPLICATION = 'WEBTSA.wsgi.application'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'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 = 'WEBTSA.wsgi.application'

# Database
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'Internal',
},
'tsa': {
'ENGINE': "django_pyodbc",
'HOST': DATABASE_HOST,
'USER': DATABASE_USER,
'PASSWORD': DATABASE_PASSWORD,
'NAME': "TSA_Catalog",
'OPTIONS': {
'host_is_server': False,
'encoding': 'utf-8'
}
}
}
DATABASES = {}
for database in data['databases']:
DATABASES[database['name']] = {
'ENGINE': database['engine'],
'NAME': database['schema'],
'USER': database['user'],
'PASSWORD': database['password'],
'HOST': database['host'],
'PORT': database['port'],
'OPTIONS': database['options']
}


# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
Expand All @@ -77,3 +101,5 @@
USE_L10N = True

USE_TZ = True

DATABASE_ROUTERS = ['WEBTSA.db_routers.DataSeriesRouter']
6 changes: 1 addition & 5 deletions src/WEBTSA/settings/development.py
@@ -1,11 +1,7 @@
from WEBTSA.settings.base import *

DATABASE_PATH = os.path.join('Internal')
DATABASES['default']['NAME'] = DATABASE_PATH;

DEBUG = True
TEMPLATE_DEBUG = True

STATIC_URL = '/static/'

SITE_URL = ''
SITE_URL = ''
18 changes: 6 additions & 12 deletions src/WEBTSA/settings/production.py
@@ -1,23 +1,17 @@
import sys
import django

from WEBTSA.settings.base import *

#For error logging (helicon zoo error trace logging doesn't work)
#sys.stderr = open('err.log', 'w')

DATABASE_PATH = os.path.join(BASE_DIR, os.pardir, 'Internal')
DATABASES['default']['NAME'] = DATABASE_PATH;
DEBUG = False
TEMPLATE_DEBUG = False

DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = ['localhost', '127.0.0.1', data['host']]

SITE_ROOT = os.environ['APPL_PHYSICAL_PATH']
SITE_URL = os.environ['APPL_VIRTUAL_PATH'] + "/"

STATIC_ROOT = os.path.join(SITE_ROOT, 'static')
STATIC_URL = SITE_URL + 'static/'

INSTALLED_APPS += (
'ganalytics',
)

GANALYTICS_TRACKING_CODE = 'UA-39768655-2'
django.setup()
11 changes: 4 additions & 7 deletions src/WEBTSA/settings/sandbox.py
@@ -1,18 +1,15 @@
import sys
from WEBTSA.settings.base import *
import django

#For error logging (helicon zoo error trace logging doesn't work)
#sys.stderr = open('err.log', 'w')
from WEBTSA.settings.base import *

DATABASE_PATH = os.path.join(BASE_DIR, os.pardir, 'Internal')
DATABASES['default']['NAME'] = DATABASE_PATH;

DEBUG = True
TEMPLATE_DEBUG = True
DEPLOYED = True

SITE_ROOT = os.environ['APPL_PHYSICAL_PATH']
SITE_URL = os.environ['APPL_VIRTUAL_PATH'] + "/"

STATIC_ROOT = os.path.join(SITE_ROOT, 'static')
STATIC_URL = SITE_URL + 'static/'

django.setup()
32 changes: 32 additions & 0 deletions src/WEBTSA/settings/settings.json
@@ -0,0 +1,32 @@
{
"secret_key": "!#f33z*)w$^0pi7c1r(807j4n6g*o&pt9@ar-17*i7nngiug8!",
"host": "data.uwrl.usu.edu",
"databases": [
{
"name": "default",
"schema": "TSA_Config",
"engine": "sql_server.pyodbc",
"user": "django",
"password": "djangoapp!",
"host": "localhost",
"port": "3306",
"options": {
"driver": "SQL Server Native Client 11.0",
"host_is_server": "False"
}
},
{
"name": "tsa",
"schema": "TSA_Catalog",
"engine": "sql_server.pyodbc",
"user": "WebApplication",
"password": "W3bAppl1c4t10n!",
"host": "iutahdbs.uwrl.usu.edu",
"port": "3306",
"options": {
"driver": "SQL Server Native Client 11.0",
"host_is_server": "False"
}
}
]
}
16 changes: 16 additions & 0 deletions src/WEBTSA/settings/settings_template.json
@@ -0,0 +1,16 @@
{
"secret_key": "[secret key goes here]",
"media_files_dir": "[folder in which the media files go]",
"host": "(for deployment only) [domain name of the production server where it's going to be deployed]",
"databases": [
{
"name": "default",
"schema": "[database name goes here]",
"engine": "[database engine goes here. (django.db.backends.mysql)]",
"user": "[database username goes here]",
"password": "[database password goes here]",
"host": "[database host goes here] (localhost)",
"port": "[database connection port goes here] (3306)"
}
]
}
35 changes: 10 additions & 25 deletions src/WEBTSA/urls.py
@@ -1,30 +1,15 @@
from django.conf import settings
from django.conf.urls import patterns, include, url

from django.conf.urls import include, url
from django.contrib import admin
from tastypie.api import Api

from webtsaservices.api import DataSeriesResource, SitesResource, SourcesDataServicesResource, \
VariableCategoriesResource, VariablesResource, QualityControlLevelsResource, SearchFacetsResource

from webtsainterface.views import TsaView, DebugView
from django.conf import settings

from webtsainterface.views import TsaView
from webtsainterface.api import v1_api

admin.autodiscover()

v1_api = Api(api_name='v1')
v1_api.register(SourcesDataServicesResource())
v1_api.register(DataSeriesResource())
v1_api.register(SitesResource())
v1_api.register(VariableCategoriesResource())
v1_api.register(VariablesResource())
v1_api.register(QualityControlLevelsResource())
v1_api.register(SearchFacetsResource())

BASE_URL = settings.SITE_URL[1:]

urlpatterns = patterns('',
url(r'^' + BASE_URL + '$', TsaView.as_view(), name='tsa-application'),
url(r'^' + BASE_URL + 'admin/', include(admin.site.urls)),
url(r'^' + BASE_URL + 'api/', include(v1_api.urls))
)
urlpatterns = [
url(r'^' + settings.SITE_URL + '$', TsaView.as_view(), name='tsa-application'),
url(r'^' + settings.SITE_URL + 'api/', include(v1_api.urls)),
url(r'^' + settings.SITE_URL + 'admin/', include(admin.site.urls)),
url(r'^' + settings.SITE_URL + 'select2/', include('select2.urls')),
]
48 changes: 47 additions & 1 deletion src/webtsainterface/admin.py
@@ -1,3 +1,49 @@
from django.contrib import admin
from django import forms
from select2 import fields as select_fields

# Register your models here.
from webtsainterface.models import SearchFacet, DataSeriesField
from webtsaservices.models import DataSeries


class SearchFacetForm(forms.ModelForm):
keyfield = select_fields.ChoiceField(choices=DataSeriesField.fields.get_field_choices(),
overlay="Choose a field...")
namefields = select_fields.MultipleChoiceField(choices=DataSeriesField.fields.get_field_choices(),
overlay="Choose the name fields...")
selected = forms.ChoiceField(required=False)

def get_valid_field(self, name):
field, created = DataSeriesField.fields.get_or_create(field_name=name)
return field

def clean_keyfield(self):
return self.get_valid_field(self.data[u'keyfield'])

def clean_namefields(self):
field_list = self.data[u'namefields']
if not isinstance(field_list, list):
field_list = [field_list]

fields = []
for field in field_list:
fields.append(self.get_valid_field(field))
return fields

def is_valid(self):
values = list(DataSeries.objects.order_by(self.data[u'keyfield']).values(self.data[u'keyfield']).distinct())
choices = tuple([(value_object[self.data[u'keyfield']], value_object[self.data[u'keyfield']]) for value_object in values])
self.fields[u'selected'].choices = choices
return super(SearchFacetForm, self).is_valid()

class Media:
js = ('js/admin.js', )

class Meta:
model = SearchFacet
fields = '__all__'


@admin.register(SearchFacet)
class SearchFacetAdmin(admin.ModelAdmin):
form = SearchFacetForm

0 comments on commit ec6615f

Please sign in to comment.