Django Learning Week - January 30, 2017

python django

The designated role at my current job is being a frontend web developer. However, part of my responsibilities involved collaborating with the backend developers to keep the frontend and backend integration smooth. We are using the Python web framework, Django to run our sites.

For my daily tasks, I only need to be familiar with a small subset of Django. However, Django has a lot of features that most developers won’t ever use or need.

I am curious if there are some features in Django that are glossed over but are actually very useful. It might be a feature that I am reinventing on my own. It might be a native feature that I have passed in favor of third party libraries.

So I decided to dedicate this week to learning some of the more uncommon parts of the framework.

The libraries to learn

Jinja2

While the Django Template Language(DTL) is powerful, I was interested in trying out other template engines that can integrated to Django.

Jinja2 is an alternate templating engine that is supported out of the box by Django. At first glance, it seems very similar to the DTL.

But I discovered that it has features that is not supported in the default template engine. [Macros, calls, block assignments] are some features that you can’t find in DTL.

The steps below are what I did to setup Jinja2 for Django.

  1. I added an additional configuration in TEMPLATES settings variable
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [os.path.join(BASE_DIR, 'jinja2')],
        'APP_DIRS': True,
        'OPTIONS': {'environment': 'learn_django_features.jinja2.Environment',}, 
    },
  1. I created jinja2.py file and added this configuration
from django.contrib.staticfiles.storage import staticfiles_storage
    from django.urls import reverse

    from jinja2 import Environment


    def environment(**options):
        env = Environment(**options)
        env.globals.update({
            'static': staticfiles_storage.url,
            'url': reverse,
        })
        return env
  1. I setup the urls
    from django.conf.urls import url

    from checklist.views import ChecklistHomeView

    urlpatterns = [
        url(r'^checklist/', ChecklistHomeView.as_view(), name='checklist_home'),
    ]
  1. I created the view
    from django.views.generic import TemplateView

    class ChecklistHomeView(TemplateView):
        template_name = 'home.html'
  1. I created a the template in the jinja2 folder
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        {% macro hello_world(name='Arthur') -%} 
            <div>Hello World from {{ name }}!</div>
        {%- endmacro %}
        
        {{ hello_world() }}
    </body>
    </html>

Done! I am now able to write Jinja2 templates in my Django installation.

Postgres

Since I started my career in Web Development, the defacto relational database was MySQL. I learned all my SQL skills in that language.

Over time, new competitors appeared. This week, I am mainly interested in Postgres. Why? It doesn’t have licensing problems, it has strong support and is very reliable.

Since I am using a Mac, I opt to use Postgresapp for its ease of installation. After installing it, I have to setup the path in my .zshenv file

    export PATH=<path to Postgres bin>:$PATH

After that, I have to install psycopg2 adapter in order for the Django Postgres integration to work

    pip install psycopg2

I then applied my migrations

    python manage.py migrate

Testing

Although there are a lot of framework choices, I wanted to go with the most painless solution. I opted to just use the built-in testing framework, unittest.

I created tests.py file to house my test. I created a simple boolean test to check if the testing framework has been setup properly. I also created tests that checks for a 200 response when requesting for the home and admin page.

I did not add more complicated tests because I just want to learn how to setup the unit testing framework.

Thoughts

Cut down on the number of libraries to try

When I started this endeavor, I wanted to try a lot of libraries. But I knew that I should pick only a few libraries to make it feasible. So I set the arbitrary limit to 1 library per weekday.

It turned out that even that wasn’t enough. When I tried replacing DTL with Jinja2, I expected the integration to be quick and painless. It turned out to be more work than I estimated. I was barely able to explore Jinja2’s features. For Postgres, I was only able to demonstrate that I can connect to the database from Django. I wasn’t able to run any complex queries or benchmarks on it.

I didn’t factor in the unknowns unknowns. It led me to hastily integrate libraries without deeply learning about them. Next time, it is better to just focus on even fewer libraries so that I can have time to experiment with them.

Learn about deployment process

While I was trying to learn Django this week, my ignorance of the deployment side of web development was clearly shown. I used to think that the line between a developer and a devops/systems guy is clearly delineated.

With the advent of containerization and the cloud backend, a developer must at least have some basic knowledge on this aspect of web development to be relevant. Containerization and distributed systems are getting more important.

The next time that I would do a sprint like this, I would focus on learning about WSGI servers, containers, continuous integration and more.

Conclusions

Django is a big framework. This week, I learned to easily setup testing, a relational database and an alternative template engine. But there are lots of areas that I haven’t covered.

There is still enough material to run another Django week in the future. Even so, I think I have accomplished the goal that I have set for myself at the start of the week.