ABOUT ME STEPHEN MCCULLOUGH - @SWMCC ON MOST THINGS ▸ Lead Software Engineer @ ShopKeep ▸ I help run several meetups: ▸ Pybelfast ▸ BelfastRuby ▸ BelfastElixir ▸ Previous job (MissionIQ) used Django exclusively
PURPOSE OF THIS TALK EXTEND THE DJANGO GIRLS TUTORIAL ▸ At the time of writing there are four extensions: ▸ Add more to your website ▸ Extending the base built (filters, delete) ▸ Secure your website ▸ Adding authorisation ▸ Create a comment model ▸ Adding a new model ▸ PostgresSQL installation
PURPOSE OF THIS TALK EXTEND THE DJANGO GIRLS TUTORIAL ▸ All perfectly acceptable ▸ The industry moves at a fast space ▸ If you aren’t evolving your skill set you will get left behind ▸ Two things stood out to me when reviewing the tutorials ▸ No testing ▸ No ‘services’ offered
TESTING TESTING IN PYTHON ▸ Django uses unittest ▸ You can use any library you want ▸ Its very important to add tests. It is the one true metric that separates a ‘good’ developer from a ‘bad’ one. ▸ Its not up for debate. ▸ Learn how to test your app in django. There are hundreds of pages on this subject.
SERVICES SERVICES IN A DJANGO APP ▸ Becoming more and more ‘popular’ to offer services from an ‘app’ that django produces ▸ Serves out JSON to a consumer ▸ No HTML/CSS at the django end
SERVICES CHOICES LOTS OF CHOICES……. ▸ Several choices can be made re: providing services in django: ▸ Decorators ▸ Django REST Framework ▸ Django Tastypie ▸ *BATTERIES NOT INCLUDED - GET USED TO IT!
SERVICES DJANGO-TASTYPIE ▸ We are going to authenticate our upcoming REST API using an API KEY. ▸ Tastypie has a builtin API Key gen. ▸ We use by adding a signal for the User object. ▸ When a user is created it will generate an API key. ▸ So create `services/apps.py` # services/apps.py from django.apps import AppConfig from django.contrib.auth.models import User from django.db.models import signals from tastypie.models import create_api_key class ServiceConfig(AppConfig): name = "services" def ready(self): signals.post_save.connect(create_api_key, sender=User)
SERVICES DJANGO-TASTYPIE ▸ Now we need to do some magic in __init__.py # services/__init__.py default_app_config = ‘services.apps.ServiceConfig' ▸ This is a pretty basic step but very powerful. Now any new users have a generated API key. ▸
SERVICES RESOURCES IN DJANGO-TASTYPIE ▸ Resources are the killer ‘thing’ in TastyPie ▸ Defining a resource will convert the model into an API Stream ▸ Allows us to validate requested data ▸ Modifying a response before sending onto a client # services/api.py from tastypie.resources import ModelResource from .models import Post class PostResource(ModelResource): class Meta: queryset = Post.objects.all() resource_name = 'post' allowed_methods = ['get']
SERVICES CONSUMING THE API ▸ We need to let a client consume our API # services/urls.py from django.conf.urls import url, include from tastypie.api import Api from services.api import PostResource v1_api = Api(api_name='v1') v1_api.register(PostResource()) urlpatterns = [url(r'^api/', include(v1_api.urls))] ▸ Include the URL in the project’s URL dispatcher. Note I took away the previous blog.url # mysite/urls.py from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'', include(“services.urls")), ]
SERVICES CONSUMING THE API ▸ That’s it! ▸ Go to the url http://localhost:8000/api/v1/posts/?format=json ▸ And you will see this: { "meta":{ "limit":20, "next":null, "offset":0, "previous":null, "total_count":2 }, "objects": [ { "id":1, “title”:”Django is great", “text”:”Paddy Sucks”, “author_id”:1, "resource_uri":"/api/v1/post/1/" }, { "id":2, “name":"Rails is alright", “text”:”Paddy still sucks”, “author_id”:1, "resource_uri":"/api/v1/post/2/" }, ] }