Creating a New Django App - ngageoint/voxel-globe GitHub Wiki
In voxel globe, a typical app has two parts. The order page and the processing task that runs the actual algorithm
-
./just manage startapp {app_name} -
Edit
voxel_globe/vip/urls.py, add a newurlto theurlpatternstuple -
Add the order url entry
url(r'^apps/{app_name}/', include('voxel_globe.{app_name}.urls', namespace='{app_name}')), -
Create and edit
voxel_globe/{app_name}/urls.pyto contain the new django endpoints, typicallyfrom django.conf.urls import patterns, url import voxel_globe.{app_name}.views as views urlpatterns = patterns('', url(r'^$', views.make_order, name='make_order'), url(r'^status/(?P<task_id>\d+)$', views.order_status, name="order_status"), ) -
Edit
voxel_globe/{app_name}/views.py, typicallyfrom django.shortcuts import render, redirect from .forms import {AppName}Form def make_order(request): if request.method == 'POST': form = {AppName}Form(request.POST) if form.is_valid(): import voxel_globe.{app_name}.tasks as tasks image_id = form.data['image'] task = tasks.{task_name}.apply_async(args=(image_id,)) return redirect('{app_name}:order_status', task_id=task.id) else: form = {AppName}Form() return render(request, 'order/{app_name}/html/make_order.html', {'title': 'Voxel Globe - {App Title here}', 'page_title': 'Voxel Globe - {App Page Title here}', 'form':form}) def order_status(request, task_id): from celery.result import AsyncResult task = AsyncResult(task_id) return render(request, 'order/{app_name}/html/order_status.html', {'title': 'Voxel Globe - {App Title here} Status', 'page_title': 'Voxel Globe - {App Page Title here} Status', 'task': task}) -
Create and edit
voxel_globe/{app_name}/forms.pyto add the order form, for examplefrom django import forms import voxel_globe.meta.models as models class {AppName}Form(forms.Form): image = forms.ModelChoiceField(label="Height image", queryset=models.Image.objects.filter(name__startswith='Height Map', newerVersion=None).order_by('name')) -
Create and edit
voxel_globe/{app_name}/templates/{app_name}/html/make_order.html{% extends "main/common_header.html" %} {% load staticfiles %} <!-- Include the client side javascript code --> {% block includes %} <style> </style> {% endblock %} {%block globalfunctions %} // Global functions defined outside of the jquery document ready function can be put here. {% endblock %} {% block javascript %} {% endblock %} {% block content %} <div id="mainContainer" class="main-content"> <form action="{% url '{app_name}:make_order' %}" method="post"> {% csrf_token %} <table> {{ form.as_table }} </table> <input type="submit" value="Submit" /> </form> </div> {% endblock %} -
Create and edit
voxel_globe/{app_name}/templates/{app_name}/html/order_status.html, for example{% extends "main/common_header.html" %} {% load staticfiles %} {% block includes %} <META http-equiv="refresh" content="5"> {% endblock %} {% block content %} <div id="mainContainer" class="main-content"> Task ID: {{ task.task_id }}<BR> {% if task.state == "FAILURE" %} State: {{ task.state }}<BR> Reason: {{ task.result }}<BR> {% elif task.state == "INITIALIZE" %} State: {{ task.state }}<BR> Stage: {{ task.result.stage }} {{ task.result.i }}/{{task.result.total }}<BR> {% elif task.state == "PRELOADING" %} State: {{ task.state }}<BR> Stage: {{ task.result.stage }} {{ task.result.i }}/{{task.result.total }}<BR> {% elif task.state == "PROCESSING" %} State: {{ task.state }}<BR> Stage: {{ task.result.stage }} {{ task.result.i }}/{{task.result.total }}<BR> {% if task.result.stage == "update" or task.result.stage == "color_update" %} Image: {{ task.result.image }}/{{task.result.images }} {% endif %} {% else %} State: {{ task.state }}<BR> Result: {{ task.result }}<BR> {% endif %} </div> {% endblock %} -
Add any models you will need to the newly created
models.py(uncommon) -
Edit
voxel_globe/main/templates/main/html/index.htmland add the new url to the main page<li><a href="{% url '{app_name}:make_order' %}">Order {App Name}</a></li> -
Finally, edit
vip/settings.pyand addvoxel_globe.{app_name}toINSTALLED_APPS -
Restart the httpd daemon
-
Create
voxel_globe/{app_name}/__init__.py -
Create and edit
voxel_globe/{app_name}/tasks.py, for exampleimport os from os import environ as env from celery.utils.log import get_task_logger logger = get_task_logger(__name__) import logging from voxel_globe.common_tasks import shared_task, VipTask @shared_task(base=VipTask, bind=True) def {task_name}(self, voxel_world_id, prob=0.5, , history=None): pass -
Finally, edit
vip/settings.pyand addvoxel_globe.{app_name}toINSTALLED_APPS -
Restart celery workers
TODO