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!

Django 1.6

Hi all! Today let's explore Django's newest version. This won't be in incredible detail, however. The post would be too long. We'll just see an overview. Even as we speak the developers are working on versions 1.7 and 1.8

Let's start at the top.

Django 1.3 Django 1.6
Project directory structure The structure is the same as we explored earlier. Once you open the project directory, you can see the list of apps, __init__.py, manage.py, settings.py, and urls.py. The structure here is slightly different. Once you open the project directory, there is another folder with the same name as your project. The manage.py is here too. Inside the other directory are all the apps and settings etc. While this provides a certain level of independence and atomicity, I personally am disappointed with this. I liked the older one better, and the new one takes some getting used to.
Settings The settings file contains all settings imaginable, with the ability to add your own. The default settings file shipped with 1.6 is spartan and contains only those settings that an app absolutely needs to run. Rest all need to be added, e.g. TEMPLATE_DIRS, STATIC_DIRS etc.
WSGI (Web Server Gateway Interface) No additional wsgi file Shipped with a default wsgi file (wsgi.py) to configure the interface.
Database configuration The ENGINE field is supposed to hold the DBMS you use, like sqlite3, mysql etc. The ENGINE field now has to include the full specification, i.e. django.db.backends.sqlite3, django.db.backends.mysql etc.

These are the changes I noticed and those that directly affect my coding style in Django. Feel free to comment ones that you've noticed. Until next time.

Monday, August 25, 2014

Django Templating Language - Part I

Hey guys! I know I haven't posted anything in a very long time. Exigent circumstances. Anyway, now I'm back with what may well be the most important skill in your entire Django toolkit. The templating language that Django ships makes writing pages that display multiple results mundanely easy.
In this part I'll only introduce you to templates. We'll see how to render them in the next one.

Variables:
We all know what variables are and how important they are for programming. This is how variables are represented in Django:
{{ variable_name }}

It can also be written as {{variable_name}} but the former is more readable. Let's see how to 'declare' a variable in an HTML script:

<h1>{{ heading }}</h1>
<form action = "/foo/" method = "post">
    <input type = "text" name = "bar" placeholder = "{{ placeholder }}">
</form>

Notice the difference? {{ heading }} is without quotes and {{ placeholder }} is with. The basic concept is you write the name of the variable exactly as you would write normal text. While writing normal text, you would not put quotes between the <h1>...</h1> tags but would in the <input> tag.

Right now if you just write this much code it'll print all raw data. There is no use of this code yet. However, we'll see how to render context to these templates soon enough.


Tuesday, June 17, 2014

Enforcing case sensitivity in databases

Hey guys! When I was developing today I realized that the username primary keys were not case sensitive. This is a big drawback. It reduces the number of unique and viable usernames. Even though this number is still gargantuan, case sensitive usernames are a must everywhere.
The demonstrate my problem, here's what was happening:
nitin was a username registered on my site. It was allowing entry and showing the same account when logged in with Nitin, nItin, and so on. There are 32 possibilities (2^5) of nitin being spelled with either upper or lower case characters.
Thus, 32 possible user accounts were being mapped on to only one. To do this, the username has to be checked in the query itself.

Now, select something from some_table where username = "nitin" would give you the same result for all 32 possibilities of nitin.

To avoid this, the query has to be altered:
select something from some_table where binary username = "nitin"

The binary checks for case also.
Cheers!

Thursday, June 12, 2014

File download script

Greetings! If you recall, a while ago we saw how to write a file upload script. File download is also equally important. Let's see how to write a download script now.

def download (request):
    filename = "/foo/bar/%s.%s" % (name, extension)
    f1 = open (filename, "r")
    response = HttpResponse (f1, mimetype = "type/extension")
    response['Content-Disposition'] = "attachment; filename = foo_bar.extension"
    return response


Ok, now let's examine this code:
  • Specify the file name
  • Open this file in read mode
  • Create HttpResponse object with the following parameters: filename, and mimetype.
  • MIME stands for Multipurpose Internet Mail Extension.
  • Here's a list of all MIME types. Find the appropriate one for the extension you want: http://www.sitepoint.com/web-foundations/mime-types-complete-list/
  • The second filename in the last but one line is the name and extension which the downloaded file should have. For example, your file may be .py, but you might want to make it download as .txt
  • Finally, return the HttpResponse object, and et voila! You have your file ready for download.
Note: As usual, this download will be triggered when the URL that points to the function download in the particular view is accessed.
Cheers!

Monday, June 9, 2014

The SaaS methodology

Hey guys! This one's not a tutorial. So just sit back with a cup of coffee and relax. I assure you this is going to be fun.
Up until now we've seen two names associated with programming in Django. The first one is Web Design, which is very mundane. Any Tom, Dick and Harry can visit a CMS like Wordpress nowadays and make a website for themselves.
Then we saw the slightly more colorful and yet highly misunderstood name Web Application Design, or simply Web App Design.
I'm finally going to tell you a name that is not only prestigious, but one that will blow your mind whole. It's SaaS, or Software as a Service.
I'll give you a minute to let the awesomeness sink in.
Done?
Good.
Yes, Django programming falls under software. People think that software only means the ones we open on our computers.
The Service in SaaS is not service as in social service. It means the service you provide to computers.
SaaS pieces are hosted on servers and can be accessed from anywhere with an Internet connection. They may be free or charged. The charged ones are called Proprietary Software. Also note that the free ones are not called Open Source. That's completely different. Open Source is when the underlying code is visible to the general public. Proprietary software may also be Open Source.
Furthermore, SaaS may be for only a company or organization in general or may be publicly usable. In the first case, it is hosted on indigenous servers, whose access is restricted to only within that organization. In the second, they would normally be hosted on a global server.
So how does SaaS make money? There are many models currently employed:
  • Developers can charge on a time basis (i.e. weekly, monthly, fortnightly etc) that will enable the users unlimited utility out of the software.
  • They may charge a small amount every time the software is used, which then limits the usage. This one sometimes is a bigger money maker.
  • They may also charge a very high one time price, which would transfer the ownership of the software to the buyer. The developers may further charge on maintenance and repairs.
So why did I write this article? When I first found this out several months ago while talking to my Dad (very wise man), it made me develop in Django in more earnest, all the while thinking, "Hey! I'm developing software!"
SaaS is also used while talking about RoR (Ruby on Rails). Currently the number of Rails developers greatly outnumber that of Django.
So I guess I'm hoping that by reading this article more people will be encouraged to become Django coders. Forget Sparta, we'll stand in front of Rails developers and say "THIS IS DJANGO!!".
(I have absolutely nothing against Rails or its developers by the way)
Cheers!

Sunday, June 8, 2014

An important thing

Hey guys! This is an important one. This had me stymied for a day and a half. Do not forget to commit the changes before closing the connection in the particular view if that view contains any of insert, update or delete queries. It doesn't matter with select queries, but for the aforementioned it is a must.

Friday, June 6, 2014

Displaying images

As I mentioned in a previous post, <img src = ""> does not work in Django. I mean, it does work, and that's how we are going to display images, but it doesn't work if you give local machine addresses like /home/foo/bar or C:/images/foo/bar. This is actually a good thing. Django has a very sophisticated method of handling images and other files, often called as static files.
If you open your settings.py file, you'll see two URLs: STATIC_URL and MEDIA_URL. These can be used to render static files and media in general.
Now there are two ways of doing this:
  • Using the in-built {{ STATIC_URL }} or {{ MEDIA_URL }} variables. But as I have not posted about Django's templating language, we'll put this one on the back burner. But rest assured, once you understand the templating language, how to use these will be self-evident.
  • Using full URLs, including the values specified in {{ STATIC_URL }} and {{ MEDIA_URL }}
We'll be using the second method. The only disadvantage of this method is that if the directory containing static files changes then you have to make sure that change reflects in all templates. In the first case, this would happen automatically.

Let's assume you're running your website on localhost, i.e. http://127.0.0.1/ and you want to render an image on the URL http://127.0.0.1/home. Let's also assume that the .html file behind this webpage is called home.html (wow, that's a lot of assuming).

Anyway, change into your project directory, and create a folder called static. Store all your images here. Let's assume (not again!) that you have an image called garden.jpg in the static folder, which you want to display on the homepage.

So instead of giving local machine paths, you give the path in the form of a URL.

<img src  = "http://127.0.0.1/static/garden.jpg">

Now, to validate this, open your settings.py file, and make the following changes.

STATIC_ROOT = "/foo/bar/mysite/static"
STATIC_URL = "/static/"

This will tell Django that when http://127.0.0.1/static/ (or STATIC_URL) is accessed, the path in STATIC_ROOT is to be checked.

That's all for now! Two things before we part:
  • I'm still working on the templating tutorial, to make it concise as it is a very vast topic. Once I come up with it, we'll investigate the {{ STATIC_URL }} and {{ MEDIA_URL }} business.
  • What we did here with static can also be done with media. They are two objects of the same file displaying facility, giving us more customizability. To use media, just replace static with media in all of the code above.
Cheers!

Tuesday, June 3, 2014

Backing up

Backing up your files is extremely important. If the server you've hosted your site on crashes and you don't have a copy of the files then your goose is cooked. You'll have to start from scratch.
I've written the code for backing up files and your MySQL database. Here's the link:

https://github.com/AgentK1729/File-Backup

In case you have an SQLite database, there's no need to back up the database as shown in the code, there'll be a readymade .db file. Just copy it somewhere reliable.

Troubleshooting

More often than not, your site will generate an error that will cripple its functioning. This is not a bad thing, however. Not only does it let you grow as a programmer, but also it is said that if your code executes the first time without any errors, you're not a good programmer!
I'm currently developing a commercial website and this happened to me today. I did some resizing and suddenly all my webpages showed the same message: 'Unhandled Exception'.
After hours of hunting down the source, I discovered that I deleted two apps but forgot to remove them from the INSTALLED_APPS in the settings.py.
The point of this story is that such things happen to everyone without exception. The important thing is to not panic. Here's what you do:

  • Close your eyes and take a deep breath.
  • Recall the last point where it was working.
  • Retrace the steps you took from that point till now and evaluate what might have caused the error.
The error can also be caused by some very insignificant things, which make you want to kick yourself.
  • The one I described.
  • Forgetting to 'Reload' the site in case you have hosted it on a server.
  • Not saving a file you made changes to.
So guys, remember two very important things:
  • The fact that you got an unidentifiable error means you're a better programmer than you think, because you managed to screw up a system like never before.
  • DO NOT PANIC.
Follow these two and you'll be an awesome programmer.
Cheers!

Tuesday, May 13, 2014

A break from the tutorial: Intuitive stuff

Hey guys! Let's take a break from the bombarding of information, and let's do something interesting. Let's talk about some of the features that are taken for granted in all the giant websites. You may already have noticed them. If not, double back and check them out. We'll also see how to implement them in your website.

The "Keep me logged in":
Many websites like Facebook and Gmail offer this option at the time of login. What it does is even if you close the browser/tab/window, the next time you open it it opens on your homepage. Even more fascinating, if you try to log in from some other device it you're not logged in, and you even get an alert that someone tried to access your account from an unknown location. Let's see how this is done in steps:

  • When you log in, cookies with your username are stored in your browser. If you close it and reopen it, and access that site again, it checks for that-site-specific cookies. If they are there, they take you to your homepage. Else, you're redirected to the login page.
  • To prevent multiple people accessing the account at the same type, the session is logged in to the database. The username/email is unique, so only one session of that name can be logged in to the database. If another one tries, it captures the IP address, denies it access and warns the user. (We'll see how to track IP addresses in the next article)
  • When you log in, it notes down your IP address. It is added to the list of addresses from which you frequently access that site.
  • On log out, it deletes the cookies and logs you out of the database.

The "Display n search results":
This is very easy. Just maintain a count of how many results are wanted. Assume the form method is GET:
count = int (request.GET['count'])
temp = 0
for row in cur/cur.fetchall ():
    if temp == count:
        break
    else:
        print row[0]
        temp += 1


Opening a new tab on hyperlink or button press:
For hyperlink: <a href = "foo/bar.html" target = "_blank">
For button press: <form action = "/foo/" method = "GET" target = "_blank">

The target = "_blank" does the trick. Note that it have to be inserted into form attributes and not the button's.

That's it for today! Tell me if I missed anything.
Cheers!




Friday, May 9, 2014

Custom queries III: MySQL

Ok, we saw how to connect to an SQLite database in Python. Now let's see MySQL. There's only a small difference in syntax, but it's significant. The steps, however, are the same.

Import the library
import MySQLdb as ms

Note: The as specifies an alternate name for the library. In this case, I won't have to type MySQLdb again and again. I'll just type ms.

Establish a connection
conn = ms.connect (host, username, password, database_name)

If you're running this on a machine, normally host is localhost. You'll have to create a root user, which you'll have to see how to do in your particular OS on the Internet. Provide that username and password. Then execute the command create database db_name and use this database as the fourth field.

Exhausted? So am I. I know it's a lot of effort, but trust me, the results are totally worth it.

Create a cursor as usual
cur = conn.cursor ()

Remember I said %s doesn't work in SQLite? Well, that's the only thing that works here. Let's write a query.

query = "select name from employee where empid = %s" % empid

READ THIS VERY CAREFULLY:
Now, empid is an integer, but you still have to pass is as a string. Assume empid is 1234. The query then becomes:
select name from employee where empid = 1234

Let's look at a query where we need to pass a string.
query = "select empid from employee where name = '%s'" % name

Notice the difference? %s from the first query is replace by '%s' in the second. Assume name is Douglas. The query now becomes:
select empid from employee where name = 'Douglas'

Don't worry if you're confused, go through the paragraph once again. Let it sink in.

OK, NOW RELAX AND ENJOY THE REMAINING PART.

Ok, the rest is pretty much the same.

cur.execute (query)
for row in cur.fetchall ():
    print row[0]

for row in cur: in SQLite is replaced by cur.fetchall (): in MySQL.

Alternatively, you can also use cur.fetchone () if you're sure only one row is going to be returned (for primary keys) or just want it that way.

Hope I didn't miss anything. If I did, please comment. The remaining things are the same for both SQLite and MySQL. Don't forget to commit and close the connection once the job is done.
Cheers!

Wednesday, May 7, 2014

Custom queries II: SQLite

Let's see how to connect to an SQLite database from Python. The current version is SQLite3.
Open a Python file, and import the library:
import sqlite3

Now, open a connection to the database. If the .db file already exists, connection to that file is opened, else a file of that name is created and connection is opened.
conn = sqlite3.connect ("/foo/bar/filename.db")

For executing queries, we need a cursor. So let's initialize that:
cur = conn.cursor ()

Now let's write a query.
cur.execute ("select something from some_table")

You can directly pass the string as a parameter, but for more customisations, you should initialize it separately and pass it as follows:
query = "select foo from bar"
cur.execute (query)

If you want to insert data dynamically into your query, the following is the syntax:
THIS DOES NOT WORK:
query = "select empid from employee where name = '%s'" % name
cur.execute (query)

THIS SHOULD BE DONE:
query = "select empid from employee where name = ?"
data = (name,)
cur.execute (query)

Note that data has to be a list or tuple. The syntax shown forces a single element to be a tuple. However, if there are multiple elements, just list them out normally like this:
query = "select empid, dept from employee where name = ? and salary = ?"
data = (name, sal)
cur.execute (query)

No data needs to be passed for insert and update queries, so just write those normally.
For delete, pass data in the same way as shown.
Now we need to fetch the data we get from select statement. Here's how you do it (assume I executed the previous query):
for row in cur:
    print row[0], row[1]

We selected two values here, namely empid and dept. So row[0] and row[1] will hold empid and dept respectively. This can be extended for several values.

Once you're done, you should commit the changes and close the connection.
conn.commit ()
conn.close ()

In the next article, we'll see how to handle a MySQL database in Python.
Cheers!

Custom queries I: Comparison between SQLite and MySQL

I've already said in earlier posts that you can use SQLite or MySQL as a database for your website. Recently when I was working on one I had to move to MySQL (I'll tell you why later in this article). So I thought I'll tell you guys how to transition.
But first, let's compare.

SQLite:

  • It is a lightweight DBMS
  • It is mainly used for testing and for small websites that do not generate too much data.
  • The biggest advantage is that it handles all the data through a .db file which can be transported elsewhere and used in the same way
  • It supports up to 2^64 rows (wow!)
  • On the downside, for the kind of data that giants like Facebook and Google generate, SQLite falls laughably short
  • It also has low concurrency control, which means that it crashes if too many people are trying to access the same data
The last point, the concurrency control, was the main reason I decided to switch to MySQL. The database of the website was crashing again and again. Let's look at MySQL now.

MySQL:

  • It is tough, inflexible and an extremely powerful DBMS
  • It is used by Facebook, Google, Twitter, pretty much all the web giants that exist today
  • It has very high concurrency control
  • It has the potential to store and handle an unlimited amount of data
  • It has quick crash recovery
  • There is very low chance of deadlocks
  • All in all, if you plan to build a large site this is the DBMS for you
  • The only downside is that it does not generate any file as earlier, so there has to be one native machine running the DBMS
This article is just the first of three of the series Custom queries. The reason I'm writing these three is that the query API that Django provides is good, but it does not allow custom queries (as far as my knowledge goes). For example, you want to customize search parameters and find all people that satisfy multiple conditions. To do this, Python's database API is very useful and can be used very well in Django.
In the next article, we'll see how to write custom queries for SQLite.
Cheers!

Sending emails

If you've noticed, on many sites, once you sign up, it sends you an automated confirmation email. This is another function your site should be able to perform. So today let's take a look at that.
Let's assume you have a Gmail account (if you don't, create one today, it's great!). We'll be using Gmail's email host (wow that rhymed).
Go to the settings.py file and add the following code anywhere in between.

EMAIL_USE_TLS = True
EMAIL_HOST = "smtp.gmail.com"
EMAIL_HOST_USER = "your_name@example.com"
EMAIL_HOST_PASSWORD = "your_password"
EMAIL_PORT = 587

The port number 587 is pretty standard. Also, it is very important to set TLS to True. We'll go into why later.
You have to enter your Gmail password there, but I assure you it is secure. Only the programmer(s) can see it. You may also create another common account and use those credentials instead.
Ok, now we'll need to write the Python code to send emails.
Open the views.py file in the appropriate app and write the following code:

At the top, import the Django's send_mail:
from django.core.mail import send_mail

Also import settings.py:
from django.conf import settings

Later, create this function:
def foo (request):
    title = "some title"
    message = "some message"
    host = settings.EMAIL_HOST_USER
    receiver = ["someone@example.com"]
    send_mail (title, message, host, receiver, fail_silently = False)
    return HttpResponse ("Mail sent successfully")

Some important things to note here:

  • You can directly write send_mail () and pass all the above values as arguments. I just wrote them separately so it's easier to understand.
  • receiver variable has to be a list or tuple, as Django supports sending emails to multiple people (a.k.a. multicasting).
  • fail_silently = False enables you to see what error was generated in case the email wasn't successfully sent. You can then use error handling to do stuff for each error. Or if the mail you're sending is not important (or an advertisement, 'cause people hate that), you can set it to True and set your mind at ease.
That's all for now! I just covered the basics here, there's a lot you can do with exceptions, responses etc. If you have questions, or are getting some error you can't identify the solution for, please feel free to ask in the comments.
Cheers!

Monday, May 5, 2014

Github

Hey guys! For those of you who don't know, Github is a code sharing site on which you can review and edit other people's code and post your own. I have shown you a lot of code on this blog. Some of the code like file upload, login sessions etc is the same and can be reused. So I'm going to post such pieces of code on Github for you guys to review and edit. Please do so, I would be very happy if someone improved upon the code I've written.
Also, my favorite language is Python and I do a lot of other things like software development, hacking in it. I've posted repos for these also. Please feel free to review and edit those too.

Here's the link:

https://github.com/AgentK1729

Cheers!

Sunday, May 4, 2014

File upload

One of the most common functions your website should be able to do is to upload/download pictures, PDFs and other files. In this tutorial I will show you how to create an upload script and save the files to server.
If you recall, I already showed you how to host your site on a free server. Now there are two parts to uploading files:

  1. Creating an upload script post which the file gets stored on either the server or temporary storage on your computer depending on which has more space.
  2. Copying the file from temporary storage to a permanent destination.
Let's take care of this in two parts.

Part I: Creating an upload script
Ok, first we need to create an HTML form. In a file called upload.html, type the following code.

<form action = "/uploaded/" method = "post" enctype="multipart/form-data">
Select an image: <input type = "file" name = "img"><br><br>
<input type = "submit" name = "upload" value = "Upload picture">
</form>

The enctype="multipart/form-data" is extremely important, as it specifies the encryption type of the temp file. With this done, when the 'upload' button is pressed, the file gets stored on temp storage. To render the upload page, write a simple view.

def upload (request):
    return render (request, "upload.html")

The view that we need to write for uploaded is important. But that is in part two.

Part II: Copying file to permanent storage
Now that we have the file, let's copy it to the server. We'll do this in the uploaded view.

def uploaded (request):
  file = request.FILES['img']
  dest = open ("/foo/bar/image_name.jpeg", "w")
for bit in file.read ():
dest.write (bit)
return HttpResponse ("Uploaded")

Note that the extensions of both the files should be same. We can access the temp file through request.FILES. We're reading each unit of the temp file and putting it into our permanent one.
Easy enough, right?
Don't forget to add the URLs in ulrs.py

url (r'^upload/', 'myproject.myapp.views.upload'),
url(r'^uploaded/', 'myproject.myapp.views.uploaded'),

Cheers!

Thursday, May 1, 2014

Session management: Login and logout using cookies

Hey! I know I've not posted for a long time. Truthfully, there was not much new. But there is now, so here I am! Today we'll see how to manage login and logout sessions. If you've noticed when you're on Facebook, if you accidentally close the window, reopen it and go to facebook.com, your homepage is displayed. This is because your browser has received cookies from Facebook and you're still logged in in their database.
For those who don't know, cookies are small packets of information that the user's browser stores in its cache. We'll see how to manage them in Django.

I assume you're familiar with how to use dictionaries in Python. So to create a cookie, simply do the following:
request.session[key] = value

request.session is a dictionary where all cookie data gets stored. For example,
request.session['username'] = 'someUser'

This will store the username as someUser in the browser. Do this when the user logs in. This value can be accessed many views and apps later.
In case the cookie is not erased while logging out then the next time the user opens the site he will stil be logged in.
If no one is logged in and you try to access request.session['username'], it raises a KeyError. You can use this with exception handling to check if anyone is logged into your site.

try:
    username = request.session['username']
    return HttpResponse (username)
except KeyError:
    return HttpRepsonse ("No one is logged in")

On log out, delete the cookies.
del request.session ['username']

Like this, delete all the relevant ones.
Cheers!

Saturday, March 29, 2014

Deploying a developmental website

Hey guys! I know I'm posting after a long time. Between semester projects and some of my own I almost forgot about the blog. My bad.
So in this article we'll see how to host your site on a free server. There are three advantages of doing this:

  1. Whoever you're working with can see the progress in real time, no matter where they're physically located.
  2. You would be editing the code on the server host website instead of your machine, which gives you the freedom to work on it from anywhere with an Internet connection.
  3. You need to add libraries to Django to, say, send emails, serve static files like images ('img src' doesn't work straightaway in Django) etc. The server host website will come preloaded with all these, and will constantly update itself, so you won't have to worry about it.
So let's get started. I host it on pythonanywhere.com, where it is mundanely easy. Sign up on it. There's a normal signup procedure, verification email etc. Once you're done, log in. Now you'll see several tabs: Consoles, Files, Web, Schedules, and Databases. Go to the 'Consoles' tab.
Over there, click on Bash console. In it, do the normal startproject and startapp procedure explained earlier in this tutorial.
Once done, go to the 'Files' tab and you'll see all your project files. Now copy code from whatever files you have on your machine to the respective files on the server. Alternatively, you can go to the 'Files' tab and directly upload your entire project.
Then go the 'Web' tab and click on 'Reload username.pythonanywhere.com' and your site is live!
Go back to the 'Files' tab. When you click on a particular file, the contents will be displayed in the code editor. Make your changes. Note that whenever you make any changes you have to reload the site. There's a button at the top of the code editor or you can go to the 'Web' tab as earlier.
That's all for now!
Cheers!

Thursday, January 30, 2014

Creating models

Now we have a UI up and running, but we need a powerful and reliable backend for providing and extracting data. As I said before, I'm assuming knowledge of SQL syntax. Also, as I said earlier, we'll be using SQLite3, and then upgrading to MySQL.
Now open your mysite directory. You should see a database file named trial.db. Now change into your website directory. Open the models.py file.
We're creating this basic project to mirror a college website. So let's create three classes of people: students, teaching staff and non-teaching staff. We'll create a separate class for each.
Type the following code in the models.py file.

from django.db import models
class Student (models.Model):
    name = models.CharField (max_length = 20)
    roll_no = models.IntegerField (max_length = 5, primary_key = True)

As you can see, I created a Student with a name and a roll_no (roll number). Also, I declared the roll number as a primary key. Now let's create the teaching and non-teaching staff.

class Teaching (models.Model):
    name = models.CharField (max_length = 20)
    id = models.IntegerField (max_length = 5, primary_key = True)

class Nteaching (models.Model):
    name = models.CharField (max_length = 20)
    id = models.IntegerField (max_length = 5, primary_key = True)

As you can see, I replaced roll_no with id. The definitions of all three have the same data types, but different fields. But, being familiar with SQL, you'll know the difference. Now come out of the website directory into the mysite one and run the following command:

python manage.py syncdb
You should see something like:

Creating table website_student
Creating table website_teaching
Creating table website_nteaching

This means that all the required tables have been created.
Now, to check if everything is working once more and also to add some base users, run the following command in the terminal from the mysite directory:

sqlite3 trial.db

This will open up the trial.db file with the required tables. Enter some values in the website_student, website_teaching, and website_nteaching tables as you want. If the above command issues an error, it most probably means that sqlite3 has not been installed on your system. Try:

sudo apt-get install sqlite3

If this does not work, install it through the Software Center or its equivalent in Unix systems, and for Windows, I'm afraid, you'll have to search for yourself, as I'm also currently working on Ubuntu and have no inkling as to how to do this in Windows.
In the next part we'll see how to manipulate data in the database from Django.
Cheers!

Saturday, January 11, 2014

Views

Now that we have created our admin page, we'll move on to adding webpages to our website. Feel free to tinker with the admin page, django offers amazing tools for admin documentation and control. But more on that later.
In our website, when someone clicks on a hyperlink, or does some action (specified by us) that triggers a URL change, they should be redirected to a new page. Creating this new page has two aspects: 1) Creating the user interface (in the views.py file)  2) Creating a custom URL to guide the user to that page.
As I mentioned earlier in this tutorial, I'm assuming a rudimentary knowledge of HTML, PHP, JavaScript and other web design tools. With that in mind, we'll dive straight into the GUI design.
Let's design our homepage first. Open the views.py file.

Type the following on the first line:
from django.http import HttpResponse

HTTP stands for 'Hyper Text Transfer Protocol'. The HttpResponse () function will render whatever HTML/PHP/JavaScript/CSS code we write onto the browser to make a GUI.

Now type the following code:
def home (request):
      someCode = """
      <html>
         <body>
            Hello World!
         </body>
        </html>
       """
       return HttpResponse (someCode)

Now your homepage is all set to display the ageless 'Hello World!' message. Note: The 'request' parameter is very important.
Now that we have our GUI up and running (I know it's not very impressive but you can add beauty later. Right now what we need to focus on is redirecting) we'll proceed to step 2: creating a URL.
Open the urls.py file and type the following code:
url (r'^home/', 'website.views.home'),

This code will tell django that if the URL 'localhost/home' is accessed, the code in the function home() in the app website's views.py file is to be used as GUI.
The r'^' is a part of UNIX regular expressions, about which you can read up online. But in depth knowledge of that is not required here. r'^' indicates that in localhost/home, 'localhost' can be replaced with anything (when it is deployed on the server) and the result won't change. You can put your site's domain name in place of that.
Now when you type http://127.0.0.1/home/ in your browser, you will see this 'Hello World!' message.
That's all for now! 

Wednesday, January 8, 2014

The basic admin page

Okay, now that we have created a project, let's proceed to the actual programming. Open the folder named 'mysite'.
cd mysite

We will initially use SQLite as our database engine. Although it is much less powerful than MySQL, it is easy to implement and convenient for testing. We can then upgrade to MySQL

In the 'mysite' directory, create a file called 'trial.db'. This is the database we will be using.

Open the 'settings.py' file. On line 14, in DATABASES, set 'ENGINE' to 'sqlite3'.
'ENGINE' : 'sqlite3'

In 'NAME', give the path to your 'trial.db' file.

Now scroll down to line 115, in 'INSTALLED_APPS'. You will see two lines saying 'Uncomment the next line...' Uncomment the lines under both the comments.

In the same INSTALLED_APPS, add the line 'mysite.website', This line will tell django that website is an app that is to be included. DO NOT FORGET THE COMMA.

Now go to the file called 'urls.py'. Uncomment lines 4, 5, 13, and 16.

You're set! Open the terminal, and type the following:

python manage.py syncdb

This command tells django to synchronize the database. It will ask you to create a super user. Do so. Run the command again. This time you will see a far shorter number of lines in the terminal. Once this is done, type the following:

python manage.py runserver

This command starts the development server on which we shall see the execution of the code. It will tell you to go to http://127.0.0.1/, which is localhost. Go to that url and you will see a success message.
After that, go to this url:   http://127.0.0.1/admin/

You will see a login page. Log in as the super user you created earlier for the syncdb command, and you will be redirected to a control panel.

That's all for now! Feel free to ask doubts in the comments. I may have left something out. You can also send me an email on the id specified. Adios!

Friday, January 3, 2014

Creating a project

You can download Django from the official website or search for OS specific downloads on the internet.
Let's create a sample college website complete with user login and a student database.

To create the project:

django-admin startproject mysite

This command will start a project called 'mysite'. If you open the folder labeled 'mysite'  you'll find the following things:
  • __init__.py: This is the initialization file. There is normally nothing in this file, and your app will work very well if you keep a cool, wary distance from this file.
  • manage.py: This file issues commands for running the development server, setting up and synchronizing the database etc. Again, this file is not to be altered.
  • settings.py: This file is going to be altered a lot by us. This contains all the settings for database selection, application listings, middleware classes etc.
  • urls.py: Another file that will be altered heavily. This file contains all the URLs that our website will contain and their specific webpages.


Adding applications:
The part up till now was only the project skeleton. We need to add apps to our website to make it more useful. Technically, you can have the entire website up and  running with a single app, but that's messy and a bad practice. Here, 'app' doesn't meant much the same thing as everyone knows. As we progress with the tutorial, the meaning will get clearer.

First, change into the project directory.
cd mysite

Then, add your app.
django-admin startapp website

Now, if you enter the folder labeled 'website', this is the list of files that you will see.

  • __init__.py: Again, initialization file and not to be tampered with.
  • models.py: In this file you will be defining the tables in sql that you will be using in the form of Python classes. Django knows how to translate these classes into sql tables in the appropriate form.
  • tests.py: This file is used for designing tests for the code. Many times, to check if a particular webpage is working, you have to navigate through a labyrinth of other pages to get to the desired page and look for bugs. This file automates this process, thus reducing developer effort.
  • views.py: This file is responsible for the user interface on the webpages. Here we will be using CSS, JavaScript and other languages to make our webpages more attractive.


That's all for now. We will start implementing our website in the next part of the tutorial.

Introduction

Django is a web framework that can be used to design websites in Python. It's lightweight, easy to learn and can incorporate scripts from several other languages like MySQL, JavaScript, HTML, CSS, PHP etc.
This tutorial assumes that you have a basic knowledge of Python syntax, webpage design in HTML and SQL syntax.
Keep checking for further posts.