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 newurl
to theurlpatterns
tuple -
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.py
to 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.py
to 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.html
and 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.py
and 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.py
and addvoxel_globe.{app_name}
toINSTALLED_APPS
-
Restart celery workers
TODO