Middleware in Django. In Django, middleware is just a class that executes middleware methods at the appropriate time when a request comes and goes, according to Django’s own rules.

In the Settings module of a Django project, there is a MIDDLEWARE_CLASSES variable, each of which is a middleware element, as shown below.

MIDDLEWARE = [
   'django.middleware.security.SecurityMiddleware'.'django.contrib.sessions.middleware.SessionMiddleware'.'django.middleware.common.CommonMiddleware'.'django.middleware.csrf.CsrfViewMiddleware'.'django.contrib.auth.middleware.AuthenticationMiddleware'.'django.contrib.messages.middleware.MessageMiddleware'.'django.middleware.clickjacking.XFrameOptionsMiddleware',]Copy the code

The following methods can be defined in the middleware:

process_request(self,request)

process_view(self, request, callback, callback_args, callback_kwargs)

process_template_response(self,request,response)

process_exception(self, request, exception)

process_response(self, request, response)
Copy the code

The above methods can return either None or an HttpResonse object. If None, proceed with the django rules, or if an HttpResonse object is returned directly to the user.

Custom middleware creates folders in the same directory as mange.py, creates modules, and then creates middleware classes in the modules

class RequestExeute(object):
   def process_request(self,request):
       pass
   def process_view(self, request, callback, callback_args, callback_kwargs):
       i =1
       pass
   def process_exception(self, request, exception):
       pass
   def process_response(self, request, response):
       return response
Copy the code

Registered middleware

MIDDLEWARE = [
  'django.middleware.security.SecurityMiddleware'.'django.contrib.sessions.middleware.SessionMiddleware'.'django.middleware.common.CommonMiddleware'.'django.middleware.csrf.CsrfViewMiddleware'.'django.contrib.auth.middleware.AuthenticationMiddleware'.'django.contrib.messages.middleware.MessageMiddleware'.'django.middleware.clickjacking.XFrameOptionsMiddleware'.'Path to middleware Class'
]
Copy the code

signal

Django provides “signal scheduling” to decouple the framework from performing operations. In layman’s terms, when some action occurs, a signal allows a particular sender to alert some receiver.

Django built-in signals

Model signals
   pre_init                    # Djangos modal triggers automatically before executing its constructor
   post_init                   # Djangos modal executes its constructor automatically
   pre_save                    # Djangos modal objects are automatically triggered before being saved
   post_save                   # Djangos modal objects are automatically triggered when saved
   pre_delete                  # Djangos modal objects are automatically triggered before being deleted
   post_delete                 # Django automatically triggers removal of modal objects
   m2m_changed                 This is triggered automatically when the third table (add,remove,clear) is operated with the M2M field in Djangos Modal
   class_prepared              # When the program starts, detect the modal classes in the registered APP, and automatically trigger for each class
Management signals
   pre_migrate                 The migrate command is automatically triggered before running the migrate command
   post_migrate                The migrate command is automatically triggered after you run the migrate command
Request/response signals
   request_started             The request is automatically triggered before it arrives
   request_finished            When the request ends, it is automatically triggered
   got_request_exception       The request is automatically triggered after an exception occurs
Test signals
   setting_changed             This command is automatically triggered when the configuration file is modified using test
   template_rendered           Automatic trigger when using test to test the render template
Database Wrappers
   connection_created          Automatic trigger when creating a database connection
Copy the code

For djangos built-in signals, you only need to register the specified signal, and when the application performs the corresponding operation, the registration function is automatically triggered:

The init.py file under the project

from django.core.signals import request_finished
   from django.core.signals import request_started
   from django.core.signals import got_request_exception
   from django.db.models.signals import class_prepared
   from django.db.models.signals import pre_init, post_init
   from django.db.models.signals import pre_save, post_save
   from django.db.models.signals import pre_delete, post_delete
   from django.db.models.signals import m2m_changed
   from django.db.models.signals import pre_migrate, post_migrate
   from django.test.signals import setting_changed
   from django.test.signals import template_rendered
   from django.db.backends.signals import connection_created
   def callback(sender, **kwargs):
       print("xxoo_callback")
       print(sender,kwargs)
   xxoo.connect(callback)
   # xxoo refers to the content imported above
Copy the code

Custom signal

A. Define the signal

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings"."size"])
Copy the code

B. Registration signal

def callback(sender, **kwargs):
   print("callback")
   print(sender,kwargs)
pizza_done.connect(callback)
Copy the code

C. Trigger signal

From path import pizza_done pizza_done. Send (sender=’seven’,toppings=123, size=456) Custom signals need to be triggered anywhere by the developer.

The cache

Since Django is a dynamic site, every request will be processed on data. This can become more time-consuming when the application is heavily trafficed.The simplest solution is to use: Cache. Cache saves the return value of a certain view to memory or memcache. When someone accesses it within 5 minutes, the operation in view is not performed, but is directly retrieved from memory or Redis and returned.

Django provides six types of caching:

Development and debugging

memory

file

The database

Memcache (python-memcached module)

Memcache Cache (PyliBMC module)

1, configuration,

A. Development and debugging

# this is used to start debugging, no actual internal operation
   # configuration:
       CACHES = {
           'default': {
               'BACKEND': 'django.core.cache.backends.dummy.DummyCache'.# engine
               'TIMEOUT': 300,                                               # Cache timeout (default 300, None means never expired, 0 means immediately expired)
               'OPTIONS': {'MAX_ENTRIES': 300,                                       # maximum number of caches (default 300)
                   'CULL_FREQUENCY': 3.CULL_FREQUENCY = 1/CULL_FREQUENCY
               },
               'KEY_PREFIX': ' '.# cache key prefix (default null)
               'VERSION': 1,                                                 # cache key version (default 1)
               'KEY_FUNCTION'The function name# function that generates key (default function :key)}}# customize key
   def default_key_func(key, key_prefix, version):
       """ Default function to generate keys. Constructs the key used by all other methods. By default it prepends the `key_prefix'. KEY_FUNCTION can be used to specify an alternate function with custom key making behavior. """
       return '%s:%s:%s' % (key_prefix, version, key)

   def get_key_func(key_func):
       """ Function to decide which key function to use. Defaults to ``default_key_func``. """
       if key_func is not None:
           if callable(key_func):
               return key_func
           else:
               return import_string(key_func)
       return default_key_func
Copy the code

B, memory,

# This cache stores content to variables in memory
   # configuration:
       CACHES = {
           'default': {
               'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'.'LOCATION': 'unique-snowflake',}}# Note: Other configurations are the same as the development debug version
Copy the code

C, files,

This cache saves the content to a file
   # configuration:

       CACHES = {
           'default': {
               'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache'.'LOCATION': '/var/tmp/django_cache',}}# Note: Other configurations are the same as the development debug version
Copy the code

D. Database

# This cache saves the content to the database
   # configuration:
       CACHES = {
           'default': {
               'BACKEND': 'django.core.cache.backends.db.DatabaseCache'.'LOCATION': 'my_cache_table'.SQL > select * from database;}}Run python manage.py createcacheTable to create a table
Copy the code

E, Memcache (python-memcached module)

This cache uses the python-memcached module to connect to memcache

   CACHES = {
       'default': {
           'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'.'LOCATION': '127.0.0.1:11211',
       }
   }

   CACHES = {
       'default': {
           'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'.'LOCATION': 'unix:/tmp/memcached.sock',
       }
   }   

   CACHES = {
       'default': {
           'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'.'LOCATION': [
               '172.19.26.240:11211'.'172.19.26.242:11211',]}}Copy the code

F. Memcache cache (PyliBMC module)

# This cache uses the PyliBMC module to connect to memcache
   CACHES = {
       'default': {
           'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache'.'LOCATION': '127.0.0.1:11211',
       }
   }

   CACHES = {
       'default': {
           'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache'.'LOCATION': '/tmp/memcached.sock',
       }
   }   
   CACHES = {
       'default': {
           'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache'.'LOCATION': [
               '172.19.26.240:11211'.'172.19.26.242:11211',]}}Copy the code

G. Redis cache (dependent: pip3 install Django-redis)

CACHES = {
   "default": {
       "BACKEND": "django_redis.cache.RedisCache"."LOCATION": "Redis: / / 127.0.0.1:6379"."OPTIONS": {
           "CLIENT_CLASS": "django_redis.client.DefaultClient"."CONNECTION_POOL_KWARGS": {"max_connections": 100}
           # "PASSWORD": "PASSWORD"}}}Copy the code

Link and operate in the view

from django_redis import get_redis_connection
conn = get_redis_connection("default")
Copy the code

2, application

A. Full station use

If the content exists in the cache, FetchFromCacheMiddleware is used to fetch the content and return it to the user. Before returning it to the user, determine whether the content already exists in the cache. If not, UpdateCacheMiddleware saves the cache to the cache, enabling site-wide caching

 MIDDLEWARE = [
       'django.middleware.cache.UpdateCacheMiddleware'.# Other middleware...
       'django.middleware.cache.FetchFromCacheMiddleware',
   ]

   CACHE_MIDDLEWARE_ALIAS = ""
   CACHE_MIDDLEWARE_SECONDS = ""
   CACHE_MIDDLEWARE_KEY_PREFIX = ""
Copy the code

B. Separate view cache

A: from the django. Views. Decorators. Cache import cache_page @ cache_page (60 * 15) def my_view (request) :... Method 2: from the django. Views. Decorators. Cache import cache_page urlpatterns = [url (r'^ foo/([0-9] {1, 2}) / $', cache_page(60 * 15)(my_view)),
       ]

Copy the code

C. Use of local view

TemplateTag {% load cache %} b. {% cache 5000 cache key %} Cache contents {% endcache %}Copy the code