Share
Embed
Building GIS Web Apps with Python & Django
This was a *very brief* (20minutes) look at a simple GeoDjango app (a blog with a PointField), given at the MAGIC 2014 conference (Memphis Area Geographic Council).
Brad Montgomery
November 06, 2014
Transcript
65 slides
-
Building GIS Web Apps with Python & Django ! Brad
Montgomery MEMpy: Memphis Python User Group (mempy.org) Tennessee Data Commons (tndata.org) -
Batteries Included • An object-relational mapper (ORM) • Form Validation
• Testing Tools • Migrations (recently added to Django) • Built-in apps (admin, auth, caching, sessions, sitemaps, syndication, gis, … more) -
Community • 100’s of 3rd-party, open source apps • Many
are MIT or BSD Licensed. • djangopackages.com -
Directory Structure sampleproject/! !"" blog! # !"" __init__.py! # !""
admin.py! # !"" migrations! # # $"" __init__.py! # !"" models.py! # !"" tests.py! # $"" views.py! # !"" templates/ -
Projects & Apps sampleproject/! !"" blog! # !"" __init__.py! #
!"" admin.py! # !"" migrations! # # $"" __init__.py! # !"" models.py! # !"" tests.py! # $"" views.py! # !"" templates/ Most of your work is here. -
models.py from django.contrib.auth.models import User! from django.contrib.gis.db import models! !
! class Post(models.Model):! author = models.ForeignKey(User)! title = models.CharField(max_length=128)! content = models.TextField()! slug = models.SlugField(max_length=128, unique=True)! published_on = models.DateTimeField(auto_now_add=True)! published_at = models.PointField(srid=4326)! ! objects = models.GeoManager() -
models.py from django.contrib.auth.models import User! from django.contrib.gis.db import models! !
! class Post(models.Model):! author = models.ForeignKey(User)! title = models.CharField(max_length=128)! content = models.TextField()! slug = models.SlugField(max_length=128, unique=True)! published_on = models.DateTimeField(auto_now_add=True)! published_at = models.PointField(srid=4326)! ! objects = models.GeoManager() corresponds to a database table -
models.py from django.contrib.auth.models import User! from django.contrib.gis.db import models! !
! class Post(models.Model):! author = models.ForeignKey(User)! title = models.CharField(max_length=128)! content = models.TextField()! slug = models.SlugField(max_length=128, unique=True)! published_on = models.DateTimeField(auto_now_add=True)! published_at = models.PointField(srid=4326)! ! objects = models.GeoManager() columns in the table -
models.py from django.contrib.auth.models import User! from django.contrib.gis.db import models! !
! class Post(models.Model):! author = models.ForeignKey(User)! title = models.CharField(max_length=128)! content = models.TextField()! slug = models.SlugField(max_length=128, unique=True)! published_on = models.DateTimeField(auto_now_add=True)! published_at = models.PointField(srid=4326)! ! objects = models.GeoManager() -
models.py from django.contrib.auth.models import User! from django.contrib.gis.db import models! !
! class Post(models.Model):! author = models.ForeignKey(User)! title = models.CharField(max_length=128)! content = models.TextField()! slug = models.SlugField(max_length=128, unique=True)! published_on = models.DateTimeField(auto_now_add=True)! published_at = models.PointField(srid=4326)! ! objects = models.GeoManager() -
gis fields from django.contrib.gis.db import models! ! class SomeModel(models.Model):! line
= models.LineStringField()! poly = models.PolygonField()! geometry = models.GeometryField()! ! lines = models.MultiLineStringField()! points = models.MultiPointField()! polygons = models.MultiPolygonField()! geometries = models.GeometryCollectionField()! ! objects = models.GeoManager() -
ORM/gis lookups # Get a list of all Post objects!
Post.objects.all() -
ORM/gis lookups ! # Get the city using a WKT!
City.objects.get(! ! mpoly__contains=‘POINT(-95.3385 29.7245)’! )! -
ORM/gis lookups ! # Get the city where a Post
was published! City.objects.get(! ! mpoly__contains=post.published_at! )! -
ORM/gis lookups from django.contrib.gis.measure import D! ! # Find other
posts published within 5 Miles.! radius = (post.published_at, D(mi=5))! Post.objects.filter(! published_at__distance__lte=radius! ) -
ORM/gis lookups Distance Lookups ! •distance_lt •distance_lte •distance_gt •distance_gte •dwithin
Spatial Lookups ‣bbcontains ‣bboverlaps ‣covers ‣crosses ‣overlaps ‣intersects ‣touches ‣within ‣…more! -
views.py from django.shortcuts import render_to_response! from django.template import RequestContext! from
models import Post! ! def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)! template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) -
views.py from django.shortcuts import render_to_response! from django.template import RequestContext! from
models import Post! ! def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)! template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) -
views.py from django.shortcuts import render_to_response! from django.template import RequestContext! from
models import Post! ! def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)! template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) -
views.py from django.shortcuts import render_to_response! from django.template import RequestContext! from
models import Post! ! def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)! template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) -
views.py from django.shortcuts import render_to_response! from django.template import RequestContext! from
models import Post! ! def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)! template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) -
views.py from django.shortcuts import render_to_response! from django.template import RequestContext! from
models import Post! ! def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)! template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) -
<!DOCTYPE html>! <html>! <head>! <title>! {% block title %}{% endblock
%}! </title>! </head>! ! <body>! {% block content %}{% endblock %}! </body>! </html> A base.html template -
A base.html template <!DOCTYPE html>! <html>! <head>! <title>! {% block
title %}{% endblock %}! </title>! </head>! ! <body>! {% block content %}{% endblock %}! </body>! </html> -
post.html {% extends "base.html" %}! ! {% block title %}!
{{ post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html template filters -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html -
{% extends "base.html" %}! ! {% block title %}! {{
post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} post.html template filter -
URLConf’s • Tie it all together! • Route HTTP requests
to views • May also capture values -
Root URLConf: urls.py from django.conf.urls import patterns, include, url! !
from django.contrib import admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) -
from django.conf.urls import patterns, include, url! ! from django.contrib import
admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) Root URLConf: urls.py -
from django.conf.urls import patterns, include, url! ! from django.contrib import
admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) Root URLConf: urls.py -
from django.conf.urls import patterns, include, url! ! from django.contrib import
admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) Root URLConf: urls.py -
from django.conf.urls import patterns, include, url! ! from django.contrib import
admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) Root URLConf: urls.py -
from django.conf.urls import patterns, include, url! ! from django.contrib import
admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) Root URLConf: urls.py -
An HTTP Request from django.conf.urls import patterns, include, url! !
from django.contrib import admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) blog/sample-title/ -
An HTTP Request from django.conf.urls import patterns, include, url! !
from django.contrib import admin! admin.autodiscover()! ! urlpatterns = patterns('',! url(r'^blog/(?P<post_slug>.+)/$',! 'blog.views.display_post',! name='display_post'),! url(r'^admin/', include(admin.site.urls)),! ) blog/sample-title/ -
An HTTP Request def display_post(request, post_slug): ! post = Post.objects.get(slug=post_slug)!
template_data = {'post': post}! template = "blog/post.html"! ! return render_to_response(! template,! template_data,! context_instance=RequestContext(request)! ) sample-title -
An HTTP Request {% extends "base.html" %}! ! {% block
title %}! {{ post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} sampleproject/blog/templates/blog/post.html Sample Title -
An HTTP Request {% extends "base.html" %}! ! {% block
title %}! {{ post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} sampleproject/blog/templates/blog/post.html (35, 89) -
An HTTP Request {% extends "base.html" %}! ! {% block
title %}! {{ post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} sampleproject/blog/templates/blog/post.html Lorem Ipsum... -
An HTTP Request {% extends "base.html" %}! ! {% block
title %}! {{ post.title }}! {% endblock %}! ! {% block content %}! <h1>{{ post.title }}</h1>! <p>Published at {{ post.published_at }}</p>! ! {{ post.content|urlize|linebreaks }}! ! <p>Published on:! {{ post.published_on|date:"M d, Y" }}</p>! {% endblock %} sampleproject/blog/templates/blog/post.html Nov 3, 2012 -
Want to Learn More? The Official Django Docs are great!
https://docs.djangoproject.com -
Thanks! Questions? Brad Montgomery [email protected] @bkmontgomery MEMpy 3rd Monday 6:30
pm-8:30pm @MemphisPython http://mempy.org