Sunday, August 30, 2015

How to make one view do the work of two

Hey folks! Today's is an interesting topic: making one view do two functions. In fact, you can make it do more than two; you an make them do 8 at a time. Think of it as view overloading, if you're into that kind of thing.
So let's dive into it.

Take logging into your account for example. Initially what I used to do is split this process into three views: one for displaying the login page, one for verification of credentials, and a third for displaying the profile. With the new method I will outline in this post you can do that using only two views rather than three. We'll combine displaying the login page and credential verification into one view. The way well do that will use HTTP request methods. Let's see what those are (going to take a little help from TutorialsPoint for the exact definitions):

  1. GET: This method is used to extract data that is embedded in the URL. The data is identified by a '?'. For example, in the URL "http://some.url/?data1=value1&data2=value2" the data after the '?' can be translated as {'data1':'value1', 'data2':'value2'}
  2. HEAD: This one is the same as GET, but this one only transfers status line and header section
  3. POST: This method sends data directly to the server rather than embedding it in the URL. It is used for handling sensitive data like passwords and credit card numbers. That way, when a user enters it in the browser, it cannot be seen by someone standing behind him
  4. PUT: This is an upload based method. The representations of target resource are replaced with uploaded content
  5. DELETE: As the name indicates, this method deletes all representations of the target resource
  6. CONNECT: Establishes a connection with the server
  7. OPTIONS: Describes communication options for target resource
  8. TRACE: Performs a loopback test on connection tunnel
Now each webpage can be accessed using one of those methods. you can overload a view by using an if  block to see what access method is used and do a different thing based on that.

def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        # code to authenticate user

As you can see, in this case, if the request method is GET, which it is by default, it'll just render the login page. Normally, in the login form the action will be POST since we'll be asking for passwords. So the first page will be rendered due to the GET method and the verification will be done by the POST method. So this way you can overload views.
That's all for today folks!

Thursday, July 16, 2015

How to access your Django site from a different computer

Hey guys! Today we'll see how to access your Django site from another computer. Now this won't be a problem if you've hosted on a remote server like PythonAnywhere or Heroku. But what if you have hosted it on your local machine and want to provide people with access to it?

I'm developing an online mentorship platform for my college that is hosted on the college server. So for that I had to use this concept. Before you do this, however, here's a disclaimer: only computers connected in the same network as your local machine can access your Django site. You can, of course, provide global access, but there's a lot of complicated networking stuff involved in that. Let's not go into that right now.

So let's get on with it. You know the command for hosting and accessing the site on your local machine is python manage.py runserver. This essentially gives your local machine server capabilities and lets you access it from the same machine. However, to let other machines access it, here's the command:
python manage.py runserver <ip_address>:<port_number>

Replace <ip_address> with your machine's IP address. If you don't know the IP address, do one of the following:
  • Windows: Open command prompt and type ipconfig. There'll be a field that reads IPv4 Address. That's the address you should put in your runserver command.
  • Linux/Mac: Open terminal and type ifconfig. There'll be a field that reads inet address. Now there might be two fields that read that. If you're connected by Ethernet, use the one listed under Ethernet. If you're connected by Wi-Fi, use the one listed under WLAN0
As for the <port_number>, the default port for any Django project is 8000. However, you can use any port you want with the exceptions of the ones used for say SMTP and Telnet.

Let's look at an example. If my IP address is 172.20.55.21 and I want to use the standard port, i.e. 8000, my command will look like this:
python manage.py runserver 172.20.55.21:8000

Then, any user wanting to access it, (again, from the same network, can't stress that enough) should simply type 172.20.55.21:8000 in the URL bar and he will be able to view and use the site.

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!

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!