Python simulates Django framework

Source: Internet
Author: User
This article describes in detail how to simulate the Django framework in python and understand the basic functions required by a web framework. For more information, see I. python web server implementation

Web development requires a web server first. For example, apache, but it is best to have a simple and convenient development server in the development stage,
It is easy to restart for debugging. after the development and debugging are completed, the code will be deployed to a mature, stable, and efficient web server.

#-*-Coding: UTF-8-*-from wsgiref import simple_server # define a simple web application def hello_app (environ, start_response) that outputs hello world and environment variables ): # output http header. text/plain indicates that it is plain text start_response ('2017 OK ', [('content-type', 'text/plain')]) # prepare the output content = [] content. append ('Hello World') for key, value in environ. items (): content. append ('% s: % s' % (key, value) # Output. according to the wsgi protocol, an iterator is returned, return ['\ n' if a list is returned '. join (content)] # construct the development server object, set the bound address and port, and pass the hello world application to its server = simple_server.make_server ('localhost', 8080, hello_app) # start the development server. serve_forever ()

After executing the above program, open the browser and visit a URL starting with #: 8080 to see the content contained by environ.

#-*-Coding: UTF-8-*-from wsgiref import simple_serverfrom webob import Request, Response # A feature is added by the way, is based on the parameters passed after the URL # display the corresponding content def hello_app (request): content = [] # get the get request parameter content. append ('HELLO % s' % request. GET ['name']) # output all environ variables for key, value in request. environ. items (): content. append ('% s: % s' % (key, value) response = Response (body =' \ n '. join (content) response. headers ['cont Ent-type '] = 'text/plain' return response # encapsulate the request and response def wsgi_wrapper (environ, start_response): Request = request (environ) response = hello_app (request) # The response object also implements the communication protocol with the wsgi server. # it can help us deal with the interaction with the web server. # This sentence is strange. what is the meaning of the object using parentheses .... Return response (environ, start_response) server = simple_server.make_server ('localhost', 8080, wsgi_wrapper) server. serve_forever ()

To make wsgi_wrapper more generic, you can design it as a decoration device:

#-*-Coding: UTF-8-*-from wsgiref import simple_serverfrom webob import Request, Response # write wsgi_wrapperdef wsgi_wrapper (func): def new_func (environ, start_response ): request = Request (environ) response = func (request) return response (environ, start_response) new_func. _ name _ = func. _ name _ new_func. _ doc _ = func. _ doc _ return new_func # Application @ wsgi_wrapperdef hello_app (request): content = [] content. append ('HELLO % s' % request. GET ['name']) for key, value in request. environ. items (): content. append ('% s: % s' % (key, value) response = Response (body =' \ n '. join (content) response. headers ['content-type'] = 'text/plain 'return responseserver = simple_server.make_server ('localhost', 8080, hello_app) server. serve_forever ()

III. Template
Indeed, templates are still needed. you cannot always write long html code in Response.
The template engines in python mainly include mako, genshi, and jinjia.
MakoThe main feature is that the template can easily embed Python code, and the execution efficiency is first-class;
GenshiIt is characterized by xml-based, very easy-to-understand template syntax, which is a good choice for friends who love xhtml,
Python code can also be embedded to implement complex presentation logic;
JinjaAndGenshiIt also has simple template syntax, but does not depend on the xml format. it is also suitable for designers to directly create templates,
You can also embed Python code to implement complex presentation logic.

Here, Mako is used at ttp: // pypi.python.org/pypi/mako. download python setup. py install for installation.
Simple module example:

#-*-Coding: UTF-8 -*-  Simple mako Template  Hello $ {name }!
 
 
    % For key, value in data. items ():
  • $ {Key}-$ {value}
  • % Endfor

Save it as a simple.html file, and then pass the data and name parameters to the template object, and then perform rendering, you can enter the html content

#-*-Coding: UTF-8-*-# import the template object from mako. template import Template # use the Template file name to construct the template object tmpl = Template (filename = '. /simple.html ', output_encoding = 'utf-8') # construct a simple dictionary filling template and print out print tmpl. render (name = 'Python', data = {'a': 1, 'B': 2 })

Save it as the test_template.py file, and enter the content after running:
$ Python test_template.py

  Simple mako Template  Hello python!
 
 
  • A-1
  • B-2

The following is a reconstruction of the hello_app program:
1. separate wsgi_wrapper into the general module utils. py:

# -*- coding: utf-8 -*-from webob import Requestdef wsgi_wrapper(func): def new_func(environ, start_response):  request = Request(environ)  response = func(request)  return response(environ, start_response) new_func.__name__ = func.__name__ new_func.__doc__ = func.__doc__ return new_func

2. completely separate hello_app to form a separate module controller. py:

#-*-Coding: UTF-8-*-from utils import wsgi_wrapperfrom webob import Responsefrom mako import Template # integrate the hello_app @ wsgi_wrapperdef hello_app (request) of the Template function ): tmpl = Template (filename = '. /simple.html ', output_encoding = 'utf-8') content = tmpl. render (name = request. GET ['name'], data = request. environ) return Response (body = content)

3. in this way, main. py becomes like this:

# -*- coding: utf-8 -*-from wsgiref import simple_serverfrom controller import hello_appserver = simple_server.make_server('localhost', 8080, hello_app)server.serve_forever()

IV. ORM (Object Relation Mapping)
Finally, we need to work with the database as a web application.
Sqlalchemy is used here. it is an ORM (object-relational Ing) library that provides ing between Python objects and relational databases. And Django models
The usage is similar. you can also use python code to create and operate database tables.
Sqlalchemy can also automatically map the inheritance of Python objects to implement eager loading and lazy loading, and can directly map the Model to custom
SQL statements, supporting n-plus databases, and so on. It can be said that sqlalchemy does not lose the powerful functions of Hibernate, but does not lose Python
Is concise and elegant.
Usage:

#-*-Coding: UTF-8-*-from sqlalchemy import * from sqlalchemy. orm import sessionmaker, scoped_sessionfrom sqlalchemy. ext. declarative import declarative_base # create a database engine. here we directly use the database engine: sqlite that comes with Python2.5, # directly create a database named data in the current directory. database engine = create_engine ('sqlite: // data. db') # All database operations in sqlalchemy must be managed by a session. # for session details, see: http://www.sqlalchemy.org/docs/05/session.htmlSession = Scoped_session (sessionmaker (autocommit = False, autoflush = False, bind = engine) Base = declarative_base () class Dictionary (Base ): # Name of the table corresponding to the Python object in the relational database _ tablename _ = 't_dictionary '# Automatically Defined. the parameter meanings are: database field name, field type, other options key = Column ('key', String (255), primary_key = True) value = Column ('value', String (255) # create a database Base. metadata. create_all (engine) session = Session () for item in ['Python', 'Ruby', 'Java']: # construct an object dictionary = Dictionary (key = item, value = item. upper () # tell sqlalchemy to add the object to the database session. add (dictionary) # submit the session. only database operations are performed here, and three records are added to the database session. commit () # query the data of the Dictionary object in the database for dictionary in session. query (Dictionary): print dictionary. key, dictionary. value

If you run the above code twice, an error is reported. why... Because the primary key inserted to the database already exists ....
In this way, it can be integrated into the previous controller. py file.

#-*-Coding: UTF-8-*-from utils import wsgi_wrapperfrom webob import Responsefrom mako. template import Template # import the common model module from model import Session, Dictionary @ wsgi_wrapperdef hello_app (request): session = Session () # Query all Dictionary objects dictionaries = session. query (Dictionary) # Convert the list into a Dictionary data = dict ([(dictionary. key, dictionary. value) for dictionary in dictionaries]) tmpl = Template (filename = '. /simple.html ', output_encoding = 'utf-8') content = tmpl. render (name = request. GET ['name'], data = data) return Response (body = content)

V. URL distribution control
Design different URLs for different resources. the client requests this URL, and the web application then locates and executes specific functions based on the URL requested by the user.
Providing a clean URL has many advantages:
1. readability. you can use a URL to get a rough idea of what functions it provides.
2. easy to remember and easy to input directly
3. well-designed URLs are generally shorter and more refined, and are more friendly to search engines.
Use the selector module to process url ing
Http://pypi.python.org/pypi/selector, download the source file for python setup. py install
First, put the urls configuration separately in urls. py.

# -*- coding: utf-8 -*-from controller import hello_appmappings = [('/hello/{name}', {'GET':hello_app})]

Modify main. py

#-*-Coding: UTF-8-*-from wsgiref import simple_serverfrom urls import mappingsfrom selector import Selector # build url distributor app = Selector (mappings) server = simple_server.make_server ('localhost ', 8080, app) server. serve_forever ()

Then, the name parameter can be obtained through environ ['wsgiorg. routing_args '] in hello_app,
However, wsgi_wrapper can further simplify the work of hello_app: directly parse the obtained parameters.
Passed as function parameter! Modify utils. py:

from webob import Requestdef wsgi_wrapper(func): def new_func(environ, start_response):  request = Request(environ)  position_args, keyword_args = environ.get('wsgiorg.routing_args', ((), {}))  response = func(request, *position_args, **keyword_args)  return response(environ, start_response) new_func.__name__ = func.__name__ new_func.__doc__ = func.__doc__ return new_func

Then hello_app can be changed to the following:

... @ Wsgi_wrapperdef hello_app (request, name = ''):... content = tmpl. render (name = name, data = data) return Response (body = content) execute main. py, access http: // localhost: 8080/hello/Python

Summary
The above implementation is similar to several main functional modules in the Django framework. I hope it will be helpful for your learning.

For more articles on simulating the Django framework in python, refer to the Chinese PHP website!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.