Sunday, 4 September 2016

How to write custom middlewares ?


Detailed Infor
If you don't have it you need to create the middleware folder within your app following the structure:
yourproject/yourapp/middleware
The folder middleware should be placed in the same folder as settings.py, urls, templates...
Important: Don't forget to create the __init__.py empty file inside the middleware folder so your app recognize this folder

Second: Create the middleware

Now we should create a file for our custom middleware, in this example let's supose we want a middleware that filter the users based on their IP, we create a file called filter_ip_middleware.pyinside the middleware folder with this code:
class FilterIPMiddleware(object):
    # Check if client IP is allowed
    def process_request(self, request):
        allowed_ips = ['192.168.1.1', '123.123.123.123', etc...] # Authorized ip's
        ip = request.META.get('REMOTE_ADDR') # Get client IP
        if ip not in allowed_ips:
            raise Http403 # If user is not allowed raise Error

       # If IP is allowed we don't do anything
       return None

Third: Add the middleware in our 'settings.py'

We need to look for the MIDDLEWARE_CLASSES inside the settings.py and there we need to add our middleware (Add it in the last position). It should be like:
MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
     # Above are django standard middlewares

     # Now we add here our custom middleware
     'yourapp.middleware.filter_ip_middleware.FilterIPMiddleware'
)
Done ! Now every request from every client will call your custom middleware and process your custom code !

What Is ORM ?


Detailed info:

An ORM (Object-Relational Mapping) is a tool that lets you query and manipulate data from a database using an object paradigm.
It's a completely ordinary library written in your language that encapsulates the code needed to manipulate the data, so you don't use SQL anymore, but directly an object of your language.
E.G., a completely imaginary case with a pseudo language :
You have a book class, you want to retrieve all the books of which the author is "Linus". Manually, you would do something like that :

  1. book_list = new List();sql = "SELECT book FROM library WHERE author = 'Linus'";data = query(sql); // I over simplify ...while (row = data.next()){ book = new Book(); book.setAuthor(row.get('author'); book_list.add(book);}

With an ORM, it would look like that :
  1. book_list = BookTable.query(author="Linus");

The mechanical part is taken care automatically by the ORM.
Pros and cons
Using an ORM save a lot of time because :
  • DRY : You write your data model in only one place, it's easier to update, maintain and reuse the code.
  • A lot of stuff is done automatically, from the database handling to I18N.
  • It forces you to write MVC code, and in the end your app is cleaner.
  • You don't have to write poorly formed SQL (most Web programmers really suck at it, because SQL is treated like a "sub" language whereas it's a very powerful and complex one)
  • Sanitizing, using prepared statements or transactions are as easy as calling a method.
Using an ORM is more flexible because :
  • It fits in your natural way of coding (it's your language !)
  • It abstracts the DB system, so you can change it whenever you want.
  • The model is weakly binded to the rest of the app, so you can change it or use it anywhere else.
  • It let you use OOP goodness like data inheritance without head ache.
But ORM can be a pain :
  • You have to learn it, and they are not lightweight tools;
  • You have to set it up. Same problem.
  • Performances are ok for usual queries, but a SQL master will always do better with his little hands for the big dirty works.
  • It abstracts the DB. While it's ok if you know what's happening behind the scene, it's a trap for the noobs that can write very greedy statements, like a heavy hit in a for loop...
How to learn about them ?
Well, use one. What ever the one you choose, they all use the same principles. There are a lot of ORMs around here :
If you want to try an ORM in Web programming, you'd be better off using an entire framework stack like :
  • Symfony (PHP, using Propel or Doctrine)
  • Django (Python, using a internal ORM)