Tuesday, June 9, 2015

Deploying a Django application - Part I

Well, first and foremost, this blog just crossed 1000 page views. Sincere thanks to all readers. Despite what the title indicates, this is not the last post. The world of Django is ever changing and there's always new stuff to learn. But this post (or series of posts, haven't decided yet) will show you how to deploy the project you've created to a server and make it battle ready.

I was recently drafted by my college to create and deploy an online mentorship platform. We have a mentorship process that involves scheduling meetings with mentors and discussing attendance, marks and also stuff like grievances. The college wants to make it paper free. So here I am. It's a point of pride, because I'm creating and deploying all by myself.

Anyway, first off, let's see what all we need to pull this off. Here's the list:

  1. Working Django code (duh.)
  2. A dedicated computer that will act as a server. Specifications:
    • At least 4 GB RAM (to handle multiple concurrent requests)
    • At least 500 GB Hard Disk space (to store the database and static files)
    • Django installation: same as or one compatible with the one you developed your project in
    • A static IP address that is unique within the network you want to host the service in
    • Side note: You might want to consider multiple servers if you anticipate thousands of requests per hour. Otherwise just one is OK
Have you got all this? Great! Now let's see what changes you need to make in the code to make it deployment ready. Here are a few things off the top of my head. They're pretty basic. We'll go into more details in subsequent posts. I guess I've made up my mind now :P Anyway, here they are:

  1. Change DEBUG = True to DEBUG = False in the settings file. The reason for this is that if there's an error Django gives you the comprehensive report, along with some part of the code. You don't want the users to be able to see that
  2. If you need to have that, you can make two settings files: one for development and one for production. Here's how:
    • You can have two copies of the same file, with DEBUG True in one (development) and False in the other (production)
    • Alternatively, you can have a settings_production file that will import the main settings file. That way, all the user will see is an import statement in case of an error
    • Note that all this configuration and switching between two settings files have to be registered in the manage.py file before running the application
This is the initial preparation you need to make. I'm discontinuing here so that the post will be of appropriate size and not tedious to read. Keep checking!

Monday, January 5, 2015

Django Forms

This is another example of Django's reusability. We saw how to create your own form in HTML and render it and get data from it using GET or POST methods. Again, Django does this for you. While it certainly is useful knowing how to do this on a basic level, using Django's Forms API can give you more powerful forms with richer features.

Like models.py, create a file called forms.py in the app where the form is required. Let's create a simple contact form. In forms.py:

forms.py
from django import forms

class SimpleUploadForm (forms.Form):
    name = forms.CharField (label = "Enter name")
    email = forms.EmailField (
label = "Enter email ID", required = False)
    dob = forms.DateTimeField (
label = "Enter date of birth")

As you can see, just like a model, we created a simple form. Now let's render it from a view.

views.py
from django.shortcuts import render
from forms import SimpleContactForm

def simple_contact_form (request):
        form = SimpleContactForm ()
        return render (request, "simple_contact_form.html", {"form":form})


Here, we import the SimpleContactForm class from forms.py and initialize its instance in the view. Then we pass that instance as a context to the webpage we're rendering. The view will become clearer when you see the template.

simple_contact_form.html
<html>
        <head><title>Simple Contact Form</title></head>
       
        <body>
                <form action = "" method = "POST">

                        <table>
                                {{ form.as_table }}

                        </table>
                        {% csrf_token %}
                        <input type = "submit" value = "Submit">
                </form>
        </body>
</html>


Ok now let's break this down. First, form action = "" means the page doesn't change when the button is clicked. Now, in the form, we've passed the SimpleContactForm () instance as form to the template. That will be rendered in the <form> tag. The as_table method displays the form as a table. However, that only contains <tr>, <th> and <td> tags. So we have to add the <table> and </table> tags ourselves. Another form display method is as_p.

The {% csrf_token %} protects POST from, well, CSRF. If you remember I told you to comment that line which included that middleware class. You can uncomment it now and proceed normally.
See you around!

Saturday, January 3, 2015

HTTP headers

Many times you many need the IP address of the computer that's accessing your webapp. You may want it for a survey, or cataloging that user to offer better services and what not. Today we'll see not only how to get the IP address, but a host of other client side information that can be used to fine tune your app.

Let's take the IP address for example. I once needed it to see from where the app was being accessed from the most. I wrote a tracker that would piggyback on the client's signal and work backwards all the way to the source and get me the IP address. But little did I know that Django already does that for me. The IP address and host name (ISP) is encoded in the request parameter. Let's see how to view them.

To do this we'll create a simple view. In HTML, we'll create a list that contains header name and value, and then populate it through Django.

headers.html
<html>
        <head><title>Django HTTP headers</title></head>
        <body>
                <ul>
                        {% for header in headers %}
                                <li><b>{{ header.name }}</b>: {{ header.value }}</li>
                        {% endfor %}
                </ul>
        </body>
</html>

Pretty straightforward. Now let's populate the list.

views.py
from django.shortcuts import render

class Header (object):
        def __init__ (self, name, value):
                self.name, self.value = name, value

def headers (request):
        headers = []
        headers_list = request.META.items ()
        for name, value in headers_list:
                headers.append (Header (name, value))
        return render (request, "headers.html", {"headers":headers})


Let's see what's going on here. First, we import the render function. Then, we create a class called Header for use in the templating language. We already saw this with Student in Django Templating Language - Part IV. Now, request.META contains a list of headers and its method items() returns a list of tuples with name and value. We use that to populate the list in HTML.

One more thing. Notice how I provided the context directly as a parameter in the render function call? You can do that too. There's no need to do the Template/Context schedule each time.

App specific URLs

As you may know, Django boasts reusability of apps. This means you can just copy one app from one project, plug it into another and it would still work the same way. Neat, huh? Well, admittedly, till now we've only focused on getting out projects to run. But now that we know the basics of creating a working Django project, it's time to delve deeper and take advantage of Django's rich features.

Let's start with URLs. Till now, we just went on adding URLs to the main urls.py as we developed the project. But when the number of URLs starts going into the triple digits, the urls.py file can become massive and difficult to keep track of. So let's see how to create a urls.py file in each app and direct the main file to this new one.

In the main urls.py file, add a pattern that will point to the app:

url (r'^myapp/', include('myproject.myapp.urls')),

This tells Django that whenever someone access the /myapp/ URL they should be directed to the urls.py file in that app. From here on in, all the views rendered in this app will have URLs like /myapp/foo/bar. This makes them easier to manage. There's also another advantage: you no longer need unique URLs; you can have /home/ in multiple apps. That is, /myapp1/home and /myapp2/home have the same sub URL, but are still unique as a whole.

Now, create a urls.py in the concerned app. In it:

from django.conf.urls.defaults import *
(This imports all patterns from the original urls.py file)

urlpatterns = patterns ('myproject.myapp.views',

    url(r'^foo/', 'bar'),
)

Another advantage: you don't have to type the entire path to the view; just the name suffices. Hence, from the above example, when someone accesses the /myapp/foo/ URL, the bar view from myproject.myapp.views will be rendered.

To summarize, this makes handling URLs very easy. We'll see more examples of reusability in the following tutorials.

Thursday, November 6, 2014

Django Templating Language - Part IV

OK, for this exercise, assume I have a database table (in SQLite3) that contains student names and roll numbers. Let's look at this in steps.

  1. Import everything you need in views.py:
    import sqlite3
    from django.template import Template, Context

  2. Create a data structure that will hold your records:
    class Student (object):
          def __init__ (self, name, rno):
          
          self.name = name
          
          self.rno = rno

  3. Define your view and in it extract all records of student:
    def display (request):
          conn = sqlite3.connect ("/path/to/db/dbname.db")
          cur = conn.cursor ()
          cur.execute ("select * from student")
          students = []  # Will store student records
          for row in cur:
          
          students.append (Student (row[0], row[1]))
          
          # Append to list 'students' an object of the class 'Student'

  4. Now it's time for the ol' Template/Context magic:
          t = Template ("/path/to/html/file/stud.html")
          c = Context ({'students':students})
          html = t.render (c)
          return HttpReponse (html)

  5. But we're not done yet! We don't have the HTML file in which we define how the data is to be structured:
    <html>
          {% for student in students %}
                Roll no.: {{ student.rno }}                             Name: {{ student.name }}

          {% endfor %}

    </html>

You're set! Notice how elements can be accessed in HTML using the names you defined in Python in the class Student. Neat huh? I threw a lot of information your way right now. Please comment with doubts. Until next time!

CSRF Token

I don't believe I didn't cover this before. Many of you (in fact all of you) must be getting a 'CSRF Token missing' error when you submit data using the POST method. First of all let me tell you what CSRF is.

CSRF stands for Cross Site Request Forgery. When data is submitted using the GET method, it just gets encoded in the URL. But when it is submitted using the POST method it is sent directly to the servers. During this transfer if there is some bot snooping on that site, it can intercept the data and send it's own, infected data to the site.

Anyway, coming back to Django, the solution to that error lies in Django's Templating Language. I myself am still trying to understand it. In the meantime, I found a temporary fix.
NOTE: This is a temporary fix for development websites, and should not be deployed on production websites.

Sorry for sneaking that on you like that. But it had to be done. You'll understand once I tell you how to (temporarily) fix it.

  • Open settings.py
  • Look for a tuple named MIDDLEWARE_CLASSES
  • You'll see django.middleware.csrf.CsrfViewMiddleware inclulded in it.
  • Comment that line out.

Now do you see why this is so dangerous, even though it fixes the error? You're essentially disabling Django's in built protection against CSRF (which is pretty good). NEVER deploy it on production websites. This fix is only for a temporary situation, when you want to evaluate the authenticity of some other code module.

Tuesday, November 4, 2014

Django Templating Language - Part III

We're finally here! We've already seen how to extract stuff from databases. Now let's put that to good use. Before we begin, let me explain two concepts here: Template and Context.
Template is the front end, the looks of the page. This will mean the HTML (+CSS+jQuery+whatever else) code you write.
Context means what you want to put in that page. In the earlier post, we had used the variable {{ name }}. Context will tell Python what value to pass to that variable.

First things first. Let's import the necessary stuff.
from django.template import Template, Context
from django.shortcuts import render
from django.http import HttpResponse

Now what I do is pass HTML code as string to Template make it render it. While this is a neat method, I'm sure there are others out there that I don't know. So please comment so that I'll be able to learn other (maybe more efficient) ways to render templates.
The way to do this would be to use file handling. So, in views.py:

def showName (request):
    f1 = open ("/path/to/file/something.html")
    code = ""
    for i in f1.read ():
        code += i

Hope you understand what I did there. I opened a file called something.html, and returned everything in that file in the form of the code variable.
Now, let's create a template out of that file.

def showName (request):
    f1 = open ("/path/to/file/something.html")
    code = ""
    for i in f1.read ():
        code += i
    t = Template (code)

As I said earlier, I passed file contents in the form of a string to the Template method. We'll consider the same code we used for for and if in the last post (I'm hoping you will add all the other necessities to make it valid HTML code). Now let's pass data to {{ name }} using Context.

def showName (request):
    f1 = open ("/path/to/file/something.html")
    code = ""
    for i in f1.read ():
        code += i
    t = Template (code)
    c = Context ({'name':'tejas'})

As you can see, you have to pass a dictionary as a parameter to the Context method. The keys are the variables used in the templating language, and the values are the values we want them to have. The values can be variables too. But the keys have to be strings.
Finally, let's render the page.

def showName (request):
    f1 = open ("/path/to/file/something.html")
    code = ""
    for i in f1.read ():
        code += i
    t = Template (code)
    c = Context ({'name':'tejas'})
    html = t.render (c)
    return HttpReponse (html)

The second to last statement tells the system to render the context c to the template t. Assign this to a variable and return HttpResponse of this variable.
In the next part, we'll see how to render context with content from databases. Au revoir!