Saturday, 1 April 2017

usage of css, javascript, images in django

In the last post we have seen how to use html template in django view. In this tutorial we will learn about usage of static files in django.

Before we are going to use CSS and JavaScript, we have to know why we use them. Let's start with HTML

HTML - Hyper Text Markup Language

HTML is the basic language of the web. It describes the how a web page should look. When a browser loads the web page it reads the HTML instructions line by line and follows it to present the web page.
Once the HTML instructions in the are completed then the browser stops working, because the HTML program is over.

CSS - Cascading Style Sheets

You may arise a question that we have HTML why we need CSS.

In above picture we are comparing the HTML and HTML + CSS.
HTML just provides us basic structure of a web page, If we apply styles(CSS) to it we can make awesome web pages. 

JavaScript

By using HTML + CSS can only provide then best presentation, but user can't able to interact with the web page. Here comes our superman JavaScript.

JavaScript allows a user to interact with the web page.
For example,
mouse over me
If you mouse over the above box, it will say thanks.
By using JavaScript we can make web page more lively.
We can make animations, games, etc. by using HTML + CSS + JavaScript
Best Websites using JavaScript
http://www.filippobello.com/portfolio
http://www.legworkstudio.com/

Now, It's time to use the static files in our django application.
If you don't setup static settings yet, setup static settings in settings.py

static/img/books_back.jpg
It is the background image used in the template.
static/css/main.css
html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  min-height: 85%;

  /* Equal to height of footer */
  /* But also accounting for potential margin-bottom of last child */
  margin-bottom: -50px;
  background: #ece4e4;
  background-image: url("/static/img/books_back.jpg");
  background-repeat: no-repeat;
}
.footer,
.push {
  height: 50px;
}
.header{
    height: 50px;
    background: #d4d0d0;
    line-height: 2.5;
    text-align: center;
    font-size: 17pt;
    color: green;
    font-weight: 600;
}
.footer{
    line-height: 3.5;
    background: #d4d0d0;
    text-align: center;
    vertical-align: text-bottom;
}

static/js/main.js
alert("Javascript Test");
console.log("Javascript is working");

templates/home.html

{% load  static %}
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<head>
 <title> Library Management </title>
</head>
<body>
 <div class="header">Library Management</div>
    <div class="wrapper">
     <div class="container"> 
       <h2><a href="#" class="btn btn-primary">Login</a></h2>
       <h2><a href="#" class="btn btn-primary">Register</a></h2>
      </div>
     </div>
    </div>
    <div class="push"></div>
  </div>
  <footer class="footer">copyrights &copy; 2017</footer>
</body>
<script type="text/javascript" src="{% static 'js/main.js' %}"></script>
</html>


  • {% load  static %}  will load the built-in template tags from the static library.
  • static is a built-in template tag that will return the static path.
  • {% static 'css/main.css' %} is equivalent to static/css/main.css
  • If it works fine you will get an alert message.

Friday, 31 March 2017

django usage of template and view

django usage of template and view
django templates & views

In the last blog post we have seen how to write models for project. In this blog post we are going learn about usage of templates in django views.

Before start writing the view read the django request life cycle for better understanding.

Url dispatcher passes the request to the view. View is responsible for the processing of the request. As we know django follows the MVT architecture.

M -  model
V  -  view
T  -  template

  1. Model's allow us to connect with the databases for information.
  2. View takes the advantage of django models to get the information from the database[using queries] and processes it. We write business logic in views.
    We process the data in views and passes it to the template for showing processed data to the user.
  3. Template takes the processed data from the view and represent the data in a required formats like html, xml, json, etc.

We have discussed the theory part. Let's start the coding.
library_management/urls.py
from django.conf.urls import url, include

urlpatterns = [
    ....
    url(r'^', include('library.urls')),
    ....
]
This is the root urls file of our application. 'include' will add the app(library) urls. Based on the regular expression pattern users request will be served.

library/urls.py
from django.conf.urls import url
from library import views

urlpatterns = [
    url(r'^$', views.home, name="home"),
]
library/views.py
from django.shortcuts import render

def home(request):
    return render(request, 'home.html', {'say_hello': 'Hello World'})
templates/home.html
<!DOCTYPE html>
    <html> <head>
        <title> Library Management </title> </head>
    <body>
        <h1> {{ say_hello }}</h1>
    </body>
</html>
We have imported 'views' module from the library app and mapped it to url. Whenever we request the url http://localhost:8000 in the browser it will the passed to the function home.
If we observe library/views.py we have imported the render from the django shortcuts module. render takes request, template name(path from template directories) and context data(the dictionary) and renders the template with context data and returns the http response. Browser receives the response and displays it to the user.
{{ say_hello }}  replaces with Hello World. Context is a dictionary with keys and values. say_hello is a key in the context so it will replaced by it's value.
It's just like string formatting in python.

Sunday, 26 March 2017

django models and database schema design

Before we start the design our database schema, we have to create our django project. Our project is "Library Management"(For quicker understanding).

Before we start development of any software project, we should know about basics of  software development life cycle.
We have six steps in every software development life cycle.
  • Requirement gathering and analysis.
  • Design(users flow, data flow & database schema design, etc).
  • Implementation or coding.
  • Testing.
  • Deployment.
  • Maintenance.
We are not going deep into the above steps. But, We will discuss about the requirements for our project "Library Management".

Library Management allows user to register & login into the system. User can search for book with details (name, author, etc.) and can see details of book(availability, author, etc). User can request the Admin(Library staff) for book. Admin will see the request of user and will approve/reject the book and  dispatch it to the users address. After approving the book user will receive it and later he will return it within the due date. After receiving the book from the user Admin will mark it as received.

Based on the above requirement we can derive the user flow & admin flow like below diagrams.

User's flow:
library management user flow diagram
Admin/staff Flow:


library management admin flow diagram



From the above user-flow diagrams we can observe that we have to store the following details
1. User profile
2. Books Information
3. Book register(who has taken book, when returned, due date etc.)

Question yourself what to store and why so that you will understand the usage of fields in models & use appropriate names for models.
1. User Profile:
  • first name, last name, email, is staff(to distinguish users admin, user), profile picture, address
2. Book Information:
  • title, author, description, image, available books(number)
3. Book register:
  • user(who taken book), book(which book), took on(date), returned on (date), due date
Following diagram shows the entity relationship model for our project. we have chose the data type based on the data.
database schema for library management django
 we have designed our database model. Our next step is to implement it in our django project. Django is providing us "User" model with basic fields (first_name, last_name, email, is_staff, is_active, username, is_superuser). But we need to add extra fields like address and profile picture.
So, we have to customize the user model. In order to do that we have to configure the settings.py
AUTH_USER_MODEL = "library.User"
Now we are ready to write models, open the file "library/models.py" and write models init.

from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    profile_pic = models.ImageField(null=True)
    address = models.TextField(null=True)

    def __str__(self):
        return self.email


def get_upload_file_name(book_object, file_name):
        return "%s/%s/%s" % ("Book", book_object.id, file_name)


class Book(models.Model):

    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    description = models.TextField()
    image = models.ImageField(upload_to=get_upload_file_name)
    available = models.IntegerField(default=0)
    ISBN = models.CharField(max_length=50)

    def __str__(self):
        return self.title


class BookRecord(models.Model):
    user = models.ForeignKey(User)
    book = models.ForeignKey(Book)
    took_on = models.DateTimeField(auto_now_add=True)
    returned_on = models.DateTimeField(null=True)
    due_date = models.DateField()

    def __str__(self):
        return str(self.user)
Now, follow the below steps to create database
python manage.py makemigrations
This command will create the migration files in the "library/migrations" directory.
python manage.py migrate
This command will run the migrations on django orm and creates the database.
Now, our database is successfully created and ready to use it.

Django provides defiirent kinds of model fields like "CharField", "IntegerField", "Foreign Key", "ManytoMany", "Decimal Field", etc.
Based on the type of data that we are storing in the attribute we have to choose the fields.
In User model, for attribute profile pic I have chosen the "ImageField" because user will upload the image.
In BookRecord model, I have used "ForeignKey" field for attribute user because I'm making the relation between User table to BookRecord table.
Like this we have many other fields we have to choose the fields for models attributes based on the storage data. Read the django official documentation  on model fields. Still if you don't understand please comment below, so that I can clarify your doubts.

Thursday, 23 March 2017

django templates and static files


django templates and static files settings
Django template configurations

Django templates:

Django templates are just HTML files. Django creates HttpResponse for a request by rendering the given template(HTML file) with given context data. 

Django supports different types of template engines like JINJA, GENSHI, MAKO etc., Django also have it's own template engines. Template engines are configured with  "TEMPLATES" setting. It contains a list of template engines. Each template engine settings are defined in dictionary like below.
TEMPLATES = [
  {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': ["templates"],
    'APP_DIRS': True,
    'OPTIONS': {
        # ... some options here ...
     },
  },
]
We can observe in above configuration is that it contains a template engine(dictionary of settings) inside a list.
BACKEND:
It is a python path to a template engine class. It is used for rendering the templates.
Django has two built-in template engines.
  1. django.template.backends.django.DjangoTemplates 
  2. django.template.backends.jinja2.Jinja2
Both backends works fine, but they differ in template language syntax.
DIRS:
We provide "template path" to template engine. It will search for template with given path in directories (APP_DIRS, DIRS). It considers the apps from "INSTALLED_APPS" configuration.
APP_DIRS:
By default it is set to "True". This allow template engine to look for template in applications template directories.
OPTIONS: 
 It allows us to define options like template context processors, template loaders.

Django static files:

Static files, the term "static" itself tells that they do not change with time.
Usually static files includes javascript, css, images, etc.
Configuration for static files
  1. Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS
  2. Define STATIC_URL = '/static/' in settings.py file.
  3. By default django finds the static files in "static" directory under apps or in root directory. If you want to specify other directories as "static" you should add below configurations to settings.py file
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

Serving static files during development

Add the below code in root urls.py
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
]
urlpatterns += static(
    settings.MEDIA_URL,
    document_root=settings.MEDIA_ROOT
)

Serving files uploaded by a user during development

Add the below code in root urls.py
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
]

urlpatterns += static(
    settings.MEDIA_URL,
    document_root=settings.MEDIA_ROOT
)

Sunday, 19 March 2017

django project layout and settings


Let's talk about "Django" project structure in depth. You can see the complete project layout in above image.

base/project/: It is a container for our project. we can give any name to this directory and we can modify it at any time.
project/manage.py: It is created for all django projects. It is a command-line utility, it is used to interact with the "django" project in many ways.
We use below command to run development server
python manage.py runserver
"runserver" is a command which is used to run the server.
To show all available commands run the below command
python manage.py
project/project: This directory contains the project files.
project/project/__init__.py:  It is a empty file that tells python to consider the directory as a package.
project/project/settings.py: It contains all configuration settings like database settings, installed apps, root url conf etc.
project/project/urls.py: It is the root url file. It contains url patterns to map the request to the respective view to process it.
project/project/uwsgi.py: An entry-point for WSGI-compatible web servers to serve our project.
project/static: It contains the static assets like css, javascript, images, etc.
project/templates: It contains the html files that will be used to create http response to a request.
project/media: It is a path to store the media contents like files that are uploaded by users.
To get project structure that is shown in above image. we need to update settings.py file with below code.

import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR + '/media/')
MEDIA_URL = '/media/'
STATIC_URL = '/static/' 
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"), ] 

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ["templates"],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
To know more about customizing settings visit: https://docs.djangoproject.com/en/1.10/ref/settings/
project/app1: It is a python package, It contains application related files.
project/app1/templatetags: It's a directory that contains template tags of our application. Template tags helps us at the time of rendering the template. It takes the context from the template and processes it and again return it to the template.
project/app1/templatetags/__init__.py: It's empty python file, it tells python to recognize the directory as a python package.
project/app1/templatetags/tags.py: It's a python file, it contains the custom template tags that we will use it in templates.
project/app1/apps.py: It contains the application's configuration.
project/app1/models.py: It contains the models(db tables) of application. we represent our database tables with the model in django. ORM(Object Relation Mapper) converts the models to db tables. We do not use raw SQL(Structured Query Language) to query the database, instead we use django queries. ORM convert these queries into SQL equivalent code and performs the db query and again converts the relational data to python objects to make things easier.
project/app1/migrations: It contains the database migrations of application, each migration contains the database schema related code.
project/app1/migrations/__init__.py: It's empty python file, it tells python to recognize the directory as a python package.
project/app1/migrations/001_initial.py: It's a migration file of application. It contains the database schema related code, that is used to create database schema.
project/app1/__init__.py: It's a python file, it tells python to recognize the directory as a python package.
project/app1/admin.py: Django provides the inbuilt admin panel. This file contains the admin related code.
project/app1/urls.py: It contains url's that are related to the application.
project/app1/views.py: It contains the views(functions/classes) that are mapped from the url's to process the request.
project/app1/tests.py: It contains the unit tests of the application.

Saturday, 18 March 2017

django first application

Let's start our Django application from the beginning. To start our first application we have to follow the below steps. Before going to start our project learn about django project layout.

  1. Create a directory with your project name & change your directory to the project. Lets consider our project as "Library Management"
  2. mkdir Library && cd Library
    
  3. Now, create virtual environment for our project.
  4. virtualenv env
    source env/bin/activate
    
    virtual environment is now ready to use.
  5. Install Django package in environment.
  6. pip install django
    
  7. Start our project Library Management
  8. django-admin startproject library_management 
    
    After executing the above commands a new folder "library_management" will be created. Inside that folder you can see another folder "library_management" and a file "manage.py". Inside "library_management/library_management" folder you can find below files 
           __init__.py      settings.py       urls.py        wsgi.py
  9. Run the below command to test our project setup.
  10. python manage.py runserver
    
    Open your browser and hit the url http://127.0.0.1:8000/. You can see the below output.
    We have successfully setup our first django project.
    If you do not see the above output, you might have missed something. so, delete everything that you did and start from the beginning again to save our time. As we are beginners we don't know much to resolve errors.
  11. Now create an application "library" to show "hello world" as response in browser
  12. python manage.py startapp library
    
    After executing the above command in the directory you can observe that a folder with name "library" have created and a file "db.sqlite3" also. If you look inside of folder "library" you can find the following files.
    admin.py   apps.py   __init__.py   migrations   models.py    tests.py   views.py
  13. "db.sqlite3" is file database developed in python. It is best suitable for beginners. we can also use MySQL and Postgres databases. "library" is our application with its files in it.
  14. Now, open "library_management/urls.py" and replace the contents of file with below code.
  15. from django.conf.urls import url
    from django.contrib import admin
    from library import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^hello-world/$', views.hello_world),
    ]
    
    
  16. And open "library/views.py" file and replace file contents with below code
  17. from django.http import HttpResponse
    
    
    def hello_world(request):
        html_source_code = """
            <html>
            <title> Hello World</title>
                <body>
                    <h1> Hello World</h1>
                </body>
            </html>
        """
        return HttpResponse(html_source_code) 
  18. Open your web-browser and access url "http://127.0.0.1:8000/hello-world/". You can find "Hello World" as response.
Now we have successfully created "hello world" application. In the next post I will explain project, application and modules inside of it. Because it will become more lengthy if I explain it here.

Wednesday, 15 March 2017

django request lifecycle

Django Request Lifecycle
Architecture for django application
We can divide the request life cycle of the django application into three layers.
1. Browser
2. Server
3. Django

1.Browser:

Browser(client) is responsible for sending data to the server and also responsible for receiving the response back.

2. Server:

  • It receives the request from the browser, based on the request it gives response back. If we take an example of NGINX server. It can handle the 10,000 requests in a second based on the resources of the server(RAM, Processor). 
  • If it receives more than  10,000 requests in a second it creates another process to handle it. 
  • We can divide request resources in two types.  
  • 1. static resource 
  • 2. dynamic resource(It has to process the data based on request to provide resource)
  • If browser request for the static resources like images/css/javascript/etc, then NGINX  serves the request without sending it to the uWSGI server.
  • If browser requests for a dynamic request then NGINX passes it to the uWSGI to process the request. 
  • At this stage NGINX acts like a reverse proxy server. A reverse proxy server is a type of proxy server that typically sits behind the firewall in a private network and directs browser/client requests to the appropriate back-end server(uWSGI).
  • Advantages of reverse proxy server are  Load balancing, Web acceleration, Security and anonymity.

 3. Django

  • Django layer comes into the picture when request passed from nGINX to the uWSGI it  takes the request middlewares from the settings and applies on the request to modify request.
  • After applying the request middlewares it sends the request to url dispatcher. Url dispatcher is responsible for dispatching the request to a view based on the url pattern
  • Here we implement the business logic. We access the database resources by writing Django Queries.
  • The query passes to the ORM(Object Relation Mapper). ORM converts the django query into SQL(Structured Query Language) query and hits the database (MySQL/Postgres,etc). Database returns the query results in a relational table. ORM again converts these relational data into django queryset and returns back to the view.
  • View passes the context(data that's retrieved from the database) to the template.
  • Template renders the content with context data and forms the Response(HTML/XML/JSON/etc.) 
  • Again response middlewares which are defined in settings will apply and modifies the request and sends the response to the Browser(Client).