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!

Django Templating Language - Part II

Now let's look at some in-built tags. These will help you arrange data efficiently on your page. These are a lot like XML. However, the syntax is different and it is easier to manage.
If you've noticed, it says Django Templating Language. Thus, as with every other language, this one also has control structures. Let's look at a few.
(Note: We're still learning the language, and even at the end of this post the code will print raw data. I swear, we're really close to rendering data from Python. Just hang tight for one more post.)

FOR:
This simulates a for loop. It is useful when extracting data from a database and rendering on the page, especially when you don't know the number of rows that will be returned. This will simply iterate over the list and render everything.

<html>
{% for row in rows %}
<b><i>{{ row }}</i></b><br>
{% endfor %}
</html>

Let's look at this code step by step. First of all, let's map the for here with that in Python.
In Python:
for i in lst
Thus, i is row, the variable that we will use to iterate over the list of rows that the database returns. lst is rows, the list over which we need to iterate. You can name them whatever you want. Iterating over the list is useless if you don't do anything with the data. As you can see, I've simply printed the value. (As row is a variable, it is enclosed within {{ }}).
Again, this is assuming that each row has only one field. This is seldom the case. We'll see how to render rows with multiple fields when we see Python rendering in general.

IF:
This will simulate an if block. Now, elif won't work in Django 1.3, but it does in 1.6 onwards. If you want an elif statement, just put it under else and then if.
We normally compare two values in if. So Django ships two tags, ifequal and ifnotequal.

<html>
{% ifequal name "tejas" %}
<b><i>{{ name }}</i></b><br>
{% endifequal %}
</html>

<html>
{% ifnotequal name "tejas" %}
<b><i>{{ name }}</i></b><br>
{% endifnotequal %}
</html>

ifequal compares name and "tejas" to see if they're equal. It's Python equivalent would be if name == "tejas". These are the two parameters. They may be variables, strings, or any hard coded values of any data type.

ifnotequal compares name and "tejas" to see if they're not equal. It's Python equivalent would be if name != "tejas".

Great! We've learned the basics of Django's Templating Language. As usual, you can comment or inbox me with your queries. In the next post we see how to actually put data there through Python (Yay!).
You didn't Yay did you? Come on guys, a little more enthusiasm!