Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building GIS Web Apps with Python & Django

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
  1. Building GIS Web Apps with Python & Django ! Brad

    Montgomery MEMpy: Memphis Python User Group (mempy.org) Tennessee Data Commons (tndata.org)
  2. 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)
  3. Community • 100’s of 3rd-party, open source apps • Many

    are MIT or BSD Licensed. • djangopackages.com
  4. Directory Structure sampleproject/! !"" blog! # !"" __init__.py! # !""

    admin.py! # !"" migrations! # # $"" __init__.py! # !"" models.py! # !"" tests.py! # $"" views.py! # !"" templates/
  5. Projects & Apps sampleproject/! !"" blog! # !"" __init__.py! #

    !"" admin.py! # !"" migrations! # # $"" __init__.py! # !"" models.py! # !"" tests.py! # $"" views.py! # !"" templates/ Most of your work is here.
  6. 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()
  7. 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
  8. 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
  9. 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()
  10. 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()
  11. 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()
  12. ORM/gis lookups ! # Get the city using a WKT!

    City.objects.get(! ! mpoly__contains=‘POINT(-95.3385 29.7245)’! )!
  13. ORM/gis lookups ! # Get the city where a Post

    was published! City.objects.get(! ! mpoly__contains=post.published_at! )!
  14. 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! )
  15. 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!
  16. 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)! )
  17. 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)! )
  18. 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)! )
  19. 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)! )
  20. 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)! )
  21. 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)! )
  22. <!DOCTYPE html>! <html>! <head>! <title>! {% block title %}{% endblock

    %}! </title>! </head>! ! <body>! {% block content %}{% endblock %}! </body>! </html> A base.html template
  23. A base.html template <!DOCTYPE html>! <html>! <head>! <title>! {% block

    title %}{% endblock %}! </title>! </head>! ! <body>! {% block content %}{% endblock %}! </body>! </html>
  24. 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 %}
  25. {% 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
  26. {% 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
  27. {% 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
  28. {% 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
  29. {% 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
  30. {% 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
  31. {% 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
  32. {% 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
  33. {% 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
  34. {% 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
  35. 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)),! )
  36. 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
  37. 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
  38. 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
  39. 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
  40. 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
  41. 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/
  42. 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/
  43. 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
  44. 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
  45. 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)
  46. 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...
  47. 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

More Decks by Brad Montgomery

Other Decks in Technology