Django Mobile: Detect Mobile Browsers & Serve Different Template

django-mobile

django-mobile provides a simple way to detect mobile browsers and gives you tools at your hand to render some different templates to deliver a mobile version of your site to the user.

The idea is to keep your views exactly the same but to transparently interchange the templates used to render a response. This is done in two steps:

  1. A middleware determines the client's preference to view your site. E.g. if he wants to use the mobile flavour or the full desktop flavour.
  2. The template loader takes then care of choosing the correct templates based on the flavour detected in the middleware.

Installation

Pre-Requirements: django_mobile depends on django's session framework. So before you try to use django_mobile make sure that the sessions framework is enabled and working.

  1. Install django_mobile with your favourite python tool, e.g. with easy_install django_mobile or pip install django_mobile.
  2. Add django_mobile to your INSTALLED_APPS setting in the settings.py.
  3. Add django_mobile.middleware.MobileDetectionMiddleware to your MIDDLEWARE_CLASSES setting.
  4. Add django_mobile.middleware.SetFlavourMiddleware to your MIDDLEWARE_CLASSES setting. Make sure it's listed after MobileDetectionMiddleware and also after SessionMiddleware.
  5. Add django_mobile.loader.Loader as first item to your loaders list for TEMPLATES setting in settings.py.
  6. Add django_mobile.context_processors.flavour to your context_processors list for TEMPLATES setting. You can read more about loaders and context_processors in Django docs.

Note: If you are using Django 1.7 or older, you need to change step 5 and 6 slightly. Use the TEMPLATE_LOADERS and TEMPLATE_CONTEXT_PROCESSORS settings instead of TEMPLATES.

Now you should be able to use django-mobile in its glory. Read below of how things work and which settings can be tweaked to modify django-mobile's behaviour.

Usage

The concept of django-mobile is build around the ideas of different flavours for your site. For example the mobile version is described as one possible flavour, the desktop version as another.

This makes it possible to provide many possible designs instead of just differentiating between a full desktop experience and one mobile version. You can make multiple mobile flavours available e.g. one for mobile safari on the iPhone and Android as well as one for Opera and an extra one for the internet tablets like the iPad.

Note: By default django-mobile only distinguishes between full and mobile flavour.

After the correct flavour is somehow chosen by the middlewares, it's assigned to the request.flavour attribute. You can use this in your views to provide separate logic.

This flavour is then use to transparently choose custom templates for this special flavour. The selected template will have the current flavour prefixed to the template name you actually want to render. This means when render_to_response('index.html', ...) is called with the mobile flavour being active will actually return a response rendered with the mobile/index.html template. However if this flavoured template is not available it will gracefully fallback to the default index.html template.

In some cases its not the desired way to have a completely separate templates for each flavour. You can also use the {{ flavour }} template variable to only change small aspects of a single template. A short example:

<html>
<head>
    <title>My site {% if flavour == "mobile" %}(mobile version){% endif %}</title>
</head>
<body>
    ...
</body>
</html>

This will add (mobile version) to the title of your site if viewed with the mobile flavour enabled.

Note: The flavour template variable is only available if you have set up the django_mobile.context_processors.flavour context processor and used django's RequestContext as context instance to render the template.

Changing the current flavour

The basic use case of django-mobile is obviously to serve a mobile version of your site to users. The selection of the correct flavour is usually already done in the middlewares when your own views are called. In some cases you want to change the currently used flavour in your view or somewhere else. You can do this by simply calling django_mobile.set_flavour(flavour[, permanent=True]). The first argument is self explaining. But keep in mind that you only can pass in a flavour that you is also in your FLAVOURS setting. Otherwise set_flavour will raise a ValueError. The optional permanent parameters defines if the change of the flavour is remember for future requests of the same client.

Your users can set their desired flavour them self. They just need to specify the flavour GET parameter on a request to your site. This will permanently choose this flavour as their preference to view the site.

You can use this GET parameter to let the user select from your available flavours:

<ul>
    <li><a href="?flavour=full">Get the full experience</a>
    <li><a href="?flavour=mobile">View our mobile version</a>
    <li><a href="?flavour=ipad">View our iPad version</a>
</ul>

Notes on caching

Django is shipping with some convenience methods to easily cache your views. One of them is django.views.decorators.cache.cache_page. The problem with caching a whole page in conjunction with django-mobile is, that django's caching system is not aware of flavours. This means that if the first request to a page is served with a mobile flavour, the second request might also get a page rendered with the mobile flavour from the cache -- even if the second one was requested by a desktop browser.

django-mobile is shipping with it's own implementation of cache_page to resolve this issue. Please use django_mobile.cache.cache_page instead of django's own cache_page decorator.

You can also use django's caching middlewares django.middleware.cache.UpdateCacheMiddleware and FetchFromCacheMiddleware like you already do. But to make them aware of flavours, you need to add django_mobile.cache.middleware.FetchFromCacheFlavourMiddleware item before standard Django FetchFromCacheMiddleware in the MIDDLEWARE_CLASSES settings and django_mobile.cache.middleware.UpdateCacheFlavourMiddleware before django_mobile.cache.middleware.UpdateCacheMiddleware correspondingly.

It is necessary to split the usage of CacheMiddleware because some additional work should be done on request and response before standard caching behavior and that is not possible while using two complete middlewares in either order

Reference

django_mobile.get_flavour([request,] [default])

Get the currently active flavour. If no flavour can be determined it will return default. This can happen if set_flavour was not called before in the current request-response cycle. default defaults to the first item in the FLAVOURS setting.

django_mobile.set_flavour(flavour, [request,] [permanent])

Set the flavour to be used for request. This will raise ValueError if flavour is not in the FLAVOURS setting. You can try to set the flavour permanently for request by passing permanent=True. This may fail if you are out of a request-response cycle. request defaults to the currently active request.

django_mobile.context_processors.flavour

Context processor that adds the current flavour as flavour to the context.

django_mobile.context_processors.is_mobile

This context processor will add a is_mobile variable to the context which is True if the current flavour equals the DEFAULT_MOBILE_FLAVOUR setting.

django_mobile.middleware.SetFlavourMiddleware

Takes care of loading the stored flavour from the user's session or cookies (depending on FLAVOURS_STORAGE_BACKEND) if set. Also sets the current request to a thread-local variable. This is needed to provide get_flavour() functionality without having access to the request object.

django_mobile.middleware.MobileDetectionMiddleware

Detects if a mobile browser tries to access the site and sets the flavour to DEFAULT_MOBILE_FLAVOUR settings value in case.

django_mobile.cache.cache_page

Same as django's cache_page decorator, but wraps the view into additional decorators before and after that. Makes it possible to serve multiple flavours without getting into trouble with django's caching that doesn't know about flavours.

django_mobile.cache.vary_on_flavour_fetch django_mobile.cache.vary_on_flavour_update

Decorators created from the FetchFromCacheFlavourMiddleware and UpdateCacheFlavourMiddleware middleware.

django_mobile.cache.middleware.FetchFromCacheFlavourMiddleware

Adds X-Flavour header to request.META in process_request

django_mobile.cache.middleware.UpdateCacheFlavourMiddleware

Adds X-Flavour header to response['Vary'] in process_response so that Django's CacheMiddleware know that it should take into account the content of this header when looking up the cached content on next request to this URL.

Customization

There are some points available that let you customize the behaviour of django-mobile. Here are some possibilities listed:

MobileDetectionMiddleware

The built-in middleware to detect if the user is using a mobile browser served well in production but is far from perfect and also implemented in a very simplistic way. You can safely remove this middleware from your settings and add your own version instead. Just make sure that it calls django_mobile.set_flavour at some point to set the correct flavour for you.

If you need example how tablet detection can be implemented, you can checkout the middleware.py file in directory examples. Feel free to modify it as you like!

Settings

Here is a list of settings that are used by django-mobile and can be changed in your own settings.py:

FLAVOURS

A list of available flavours for your site.

Default: ('full', 'mobile')

DEFAULT_MOBILE_FLAVOUR

The flavour which is chosen if the built-in MobileDetectionMiddleware detects a mobile browser.

Default: 'mobile'

FLAVOURS_COOKIE_HTTPONLY

The value that get passed into HttpResponse.set_cookie's httponly argument. Set this to True if you don't want the Javascript code to be able to read the flavour cookie.

Default: False

FLAVOURS_COOKIE_KEY

The cookie name that is used for storing the selected flavour in the browser. This is only used if FLAVOURS_STORAGE_BACKEND is set to 'cookie'.

Default: 'flavour'

FLAVOURS_TEMPLATE_PREFIX

This string will be prefixed to the template names when searching for flavoured templates. This is useful if you have many flavours and want to store them in a common subdirectory. Example:

from django.template.loader import render_to_string
from django_mobile import set_flavour

set_flavour('mobile')
render_to_string('index.html') # will render 'mobile/index.html'

# now add this to settings.py
FLAVOURS_TEMPLATE_PREFIX = 'flavours/'

# and try again

set_flavour('mobile')
render_to_string('index.html') # will render 'flavours/mobile/index.html'

Default: '' (empty string)

FLAVOURS_TEMPLATE_LOADERS

django-mobile's template loader can load templates prefixed with the current flavour. Specify with this setting which loaders are used to load flavoured templates.

Default: same as TEMPLATE_LOADERS setting but without 'django_mobile.loader.Loader'.

FLAVOURS_GET_PARAMETER

Users can change the flavour they want to look at with a HTTP GET parameter. This determines the name of this parameter. Set it to None to disable.

Default: 'flavour'

FLAVOURS_SESSION_KEY

The user's preference set with the GET parameter is stored in the user's session. This setting determines which session key is used to hold this information.

Default: 'flavour'

FLAVOURS_STORAGE_BACKEND

Determines how the selected flavour is stored persistently. Available values: 'session' and 'cookie'.

Default: 'cookie'

Cache Settings

Django ships with the cached template loader django.template.loaders.cached.Loader that doesn't require to fetch the template from disk every time you want to render it. However it isn't aware of django-mobile's flavours. For this purpose you can use 'django_mobile.loader.CachedLoader' as a drop-in replacement that does exactly the same django's version but takes the different flavours into account. To use it, put the following bit into your settings.py file:

TEMPLATES = [
   {
      ...
      'OPTIONS': {
         ...
         'loaders': ('django_mobile.loader.CachedLoader', (
            'django_mobile.loader.Loader',
            'django.template.loaders.filesystem.Loader',
            'django.template.loaders.app_directories.Loader',
         )),
      }
   }
]

Download Details:
Author: gregmuellegger
Source Code: https://github.com/gregmuellegger/django-mobile
License: BSD-3-Clause License

#django  #python 

What is GEEK

Buddha Community

Django Mobile: Detect Mobile Browsers & Serve Different Template
Ahebwe  Oscar

Ahebwe Oscar

1620177818

Django admin full Customization step by step

Welcome to my blog , hey everyone in this article you learn how to customize the Django app and view in the article you will know how to register  and unregister  models from the admin view how to add filtering how to add a custom input field, and a button that triggers an action on all objects and even how to change the look of your app and page using the Django suit package let’s get started.

Database

Custom Titles of Django Admin

Exclude in Django Admin

Fields in Django Admin

#django #create super user django #customize django admin dashboard #django admin #django admin custom field display #django admin customization #django admin full customization #django admin interface #django admin register all models #django customization

Seamus  Quitzon

Seamus Quitzon

1594682206

Laravel detect mobile device and redirect mobile website htaccess

In this article, i will let you know laravel detect mobile device and redirect mobile website. So let’s see how can we detect mobile device and redirect website to the mobile website.

A web application can be open on desktops, laptops, tablets and mobiles. But a large application should be optimized for all devices means if we open it on desktop, there might be heavy resources used that would be not compatible for mobile devices. So we can redirect this website to mobile website or mobile freindly website. We generally see that if we open a website on mobile device, it redirects to like http://m.domain.com.

Here, in this article we will see two seperate example to implement this. First one would be using .htaccess file and second one is using laravel route.

Example 1: Using .htaccess file

For detacting mobile device and redirect to the mobile website, we will need to create a .htaccess file on root directory of application. So create this .htaccess file and update the following lines of code.

RewriteEngine On
RewriteCond %{QUERY_STRING} !^desktop
RewriteCond %{HTTP_USER_AGENT} "android|blackberry|googlebot-mobile|iemobile|iphone|ipod|#opera mobile|palmos|webos" [NC]
RewriteCond %{HTTP_USER_AGENT} "acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT}  "maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "wapp|wapr|webc|winw|winw|xda|xda-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "up.browser|up.link|windowssce|iemobile|mini|mmp" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "symbian|midp|wap|phone|pocket|mobile|pda|psp" [NC]
RewriteRule ^$ http://m.domain.com [L,R=302]

Example 2: Using Laravel Routes

After doing this through .htaccess, we can also detect mobile device and redirect to mobile site using laravel routes.

For doing this, we will need to create laravel routes and will need to add some lines of code to do this as written below.

function isMobile() {
    if(isset($_SERVER['HTTP_USER_AGENT'])) {
    $useragent=$_SERVER['HTTP_USER_AGENT'];
    if(preg_match('/(tablet|ipad|amazon|playbook)|(android(?!.*(mobi|opera mini)))/i', strtolower($useragent))) {
        return true ;
    } ;

    if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4))){
            return true ;
        }
    }
    return 0 ;
}
if(isMobile()) {
    include_once(app_path().'/routes/mobile_routes.php');
} else {
    require_once(app_path().'/routes/website_routes.php');
}

From both of the above methods, we can detect mobile device and redirect to their specific version of website. You can choose any of these two methods.

#laravel #detect devices in laravel #how to detect mobile device in laravel #how to redirect to a mobile device #laravel detect mobile device and redirect mobile website htaccess #laravel mobile redirection

Ahebwe  Oscar

Ahebwe Oscar

1620185280

How model queries work in Django

How model queries work in Django

Welcome to my blog, hey everyone in this article we are going to be working with queries in Django so for any web app that you build your going to want to write a query so you can retrieve information from your database so in this article I’ll be showing you all the different ways that you can write queries and it should cover about 90% of the cases that you’ll have when you’re writing your code the other 10% depend on your specific use case you may have to get more complicated but for the most part what I cover in this article should be able to help you so let’s start with the model that I have I’ve already created it.

**Read More : **How to make Chatbot in Python.

Read More : Django Admin Full Customization step by step

let’s just get into this diagram that I made so in here:

django queries aboutDescribe each parameter in Django querset

we’re making a simple query for the myModel table so we want to pull out all the information in the database so we have this variable which is gonna hold a return value and we have our myModel models so this is simply the myModel model name so whatever you named your model just make sure you specify that and we’re gonna access the objects attribute once we get that object’s attribute we can simply use the all method and this will return all the information in the database so we’re gonna start with all and then we will go into getting single items filtering that data and go to our command prompt.

Here and we’ll actually start making our queries from here to do this let’s just go ahead and run** Python manage.py shell** and I am in my project file so make sure you’re in there when you start and what this does is it gives us an interactive shell to actually start working with our data so this is a lot like the Python shell but because we did manage.py it allows us to do things a Django way and actually query our database now open up the command prompt and let’s go ahead and start making our first queries.

#django #django model queries #django orm #django queries #django query #model django query #model query #query with django

Rahim Makhani

Rahim Makhani

1616669264

On-Demand Mobile App Development Services in USA

Mobile apps are developing day-by-day and the usage of mobile apps is also increasing. There are many mobile app development company that are providing services for on-demand mobile app development services.

One of the leading mobile app development company in the USA is Nevina Infotech. It is the best known for providing on-demand app development services till now.

Our On-Demand Mobile App Development Services:-

iPhone App Development
Android App Development
iPad App Development
Game App Development
ionic App Development
Wearable App Development
Flutter App Development

#mobile app development company #mobile app development services #mobile application development services #mobile application development company #mobile app development company usa

Django Mobile: Detect Mobile Browsers & Serve Different Template

django-mobile

django-mobile provides a simple way to detect mobile browsers and gives you tools at your hand to render some different templates to deliver a mobile version of your site to the user.

The idea is to keep your views exactly the same but to transparently interchange the templates used to render a response. This is done in two steps:

  1. A middleware determines the client's preference to view your site. E.g. if he wants to use the mobile flavour or the full desktop flavour.
  2. The template loader takes then care of choosing the correct templates based on the flavour detected in the middleware.

Installation

Pre-Requirements: django_mobile depends on django's session framework. So before you try to use django_mobile make sure that the sessions framework is enabled and working.

  1. Install django_mobile with your favourite python tool, e.g. with easy_install django_mobile or pip install django_mobile.
  2. Add django_mobile to your INSTALLED_APPS setting in the settings.py.
  3. Add django_mobile.middleware.MobileDetectionMiddleware to your MIDDLEWARE_CLASSES setting.
  4. Add django_mobile.middleware.SetFlavourMiddleware to your MIDDLEWARE_CLASSES setting. Make sure it's listed after MobileDetectionMiddleware and also after SessionMiddleware.
  5. Add django_mobile.loader.Loader as first item to your loaders list for TEMPLATES setting in settings.py.
  6. Add django_mobile.context_processors.flavour to your context_processors list for TEMPLATES setting. You can read more about loaders and context_processors in Django docs.

Note: If you are using Django 1.7 or older, you need to change step 5 and 6 slightly. Use the TEMPLATE_LOADERS and TEMPLATE_CONTEXT_PROCESSORS settings instead of TEMPLATES.

Now you should be able to use django-mobile in its glory. Read below of how things work and which settings can be tweaked to modify django-mobile's behaviour.

Usage

The concept of django-mobile is build around the ideas of different flavours for your site. For example the mobile version is described as one possible flavour, the desktop version as another.

This makes it possible to provide many possible designs instead of just differentiating between a full desktop experience and one mobile version. You can make multiple mobile flavours available e.g. one for mobile safari on the iPhone and Android as well as one for Opera and an extra one for the internet tablets like the iPad.

Note: By default django-mobile only distinguishes between full and mobile flavour.

After the correct flavour is somehow chosen by the middlewares, it's assigned to the request.flavour attribute. You can use this in your views to provide separate logic.

This flavour is then use to transparently choose custom templates for this special flavour. The selected template will have the current flavour prefixed to the template name you actually want to render. This means when render_to_response('index.html', ...) is called with the mobile flavour being active will actually return a response rendered with the mobile/index.html template. However if this flavoured template is not available it will gracefully fallback to the default index.html template.

In some cases its not the desired way to have a completely separate templates for each flavour. You can also use the {{ flavour }} template variable to only change small aspects of a single template. A short example:

<html>
<head>
    <title>My site {% if flavour == "mobile" %}(mobile version){% endif %}</title>
</head>
<body>
    ...
</body>
</html>

This will add (mobile version) to the title of your site if viewed with the mobile flavour enabled.

Note: The flavour template variable is only available if you have set up the django_mobile.context_processors.flavour context processor and used django's RequestContext as context instance to render the template.

Changing the current flavour

The basic use case of django-mobile is obviously to serve a mobile version of your site to users. The selection of the correct flavour is usually already done in the middlewares when your own views are called. In some cases you want to change the currently used flavour in your view or somewhere else. You can do this by simply calling django_mobile.set_flavour(flavour[, permanent=True]). The first argument is self explaining. But keep in mind that you only can pass in a flavour that you is also in your FLAVOURS setting. Otherwise set_flavour will raise a ValueError. The optional permanent parameters defines if the change of the flavour is remember for future requests of the same client.

Your users can set their desired flavour them self. They just need to specify the flavour GET parameter on a request to your site. This will permanently choose this flavour as their preference to view the site.

You can use this GET parameter to let the user select from your available flavours:

<ul>
    <li><a href="?flavour=full">Get the full experience</a>
    <li><a href="?flavour=mobile">View our mobile version</a>
    <li><a href="?flavour=ipad">View our iPad version</a>
</ul>

Notes on caching

Django is shipping with some convenience methods to easily cache your views. One of them is django.views.decorators.cache.cache_page. The problem with caching a whole page in conjunction with django-mobile is, that django's caching system is not aware of flavours. This means that if the first request to a page is served with a mobile flavour, the second request might also get a page rendered with the mobile flavour from the cache -- even if the second one was requested by a desktop browser.

django-mobile is shipping with it's own implementation of cache_page to resolve this issue. Please use django_mobile.cache.cache_page instead of django's own cache_page decorator.

You can also use django's caching middlewares django.middleware.cache.UpdateCacheMiddleware and FetchFromCacheMiddleware like you already do. But to make them aware of flavours, you need to add django_mobile.cache.middleware.FetchFromCacheFlavourMiddleware item before standard Django FetchFromCacheMiddleware in the MIDDLEWARE_CLASSES settings and django_mobile.cache.middleware.UpdateCacheFlavourMiddleware before django_mobile.cache.middleware.UpdateCacheMiddleware correspondingly.

It is necessary to split the usage of CacheMiddleware because some additional work should be done on request and response before standard caching behavior and that is not possible while using two complete middlewares in either order

Reference

django_mobile.get_flavour([request,] [default])

Get the currently active flavour. If no flavour can be determined it will return default. This can happen if set_flavour was not called before in the current request-response cycle. default defaults to the first item in the FLAVOURS setting.

django_mobile.set_flavour(flavour, [request,] [permanent])

Set the flavour to be used for request. This will raise ValueError if flavour is not in the FLAVOURS setting. You can try to set the flavour permanently for request by passing permanent=True. This may fail if you are out of a request-response cycle. request defaults to the currently active request.

django_mobile.context_processors.flavour

Context processor that adds the current flavour as flavour to the context.

django_mobile.context_processors.is_mobile

This context processor will add a is_mobile variable to the context which is True if the current flavour equals the DEFAULT_MOBILE_FLAVOUR setting.

django_mobile.middleware.SetFlavourMiddleware

Takes care of loading the stored flavour from the user's session or cookies (depending on FLAVOURS_STORAGE_BACKEND) if set. Also sets the current request to a thread-local variable. This is needed to provide get_flavour() functionality without having access to the request object.

django_mobile.middleware.MobileDetectionMiddleware

Detects if a mobile browser tries to access the site and sets the flavour to DEFAULT_MOBILE_FLAVOUR settings value in case.

django_mobile.cache.cache_page

Same as django's cache_page decorator, but wraps the view into additional decorators before and after that. Makes it possible to serve multiple flavours without getting into trouble with django's caching that doesn't know about flavours.

django_mobile.cache.vary_on_flavour_fetch django_mobile.cache.vary_on_flavour_update

Decorators created from the FetchFromCacheFlavourMiddleware and UpdateCacheFlavourMiddleware middleware.

django_mobile.cache.middleware.FetchFromCacheFlavourMiddleware

Adds X-Flavour header to request.META in process_request

django_mobile.cache.middleware.UpdateCacheFlavourMiddleware

Adds X-Flavour header to response['Vary'] in process_response so that Django's CacheMiddleware know that it should take into account the content of this header when looking up the cached content on next request to this URL.

Customization

There are some points available that let you customize the behaviour of django-mobile. Here are some possibilities listed:

MobileDetectionMiddleware

The built-in middleware to detect if the user is using a mobile browser served well in production but is far from perfect and also implemented in a very simplistic way. You can safely remove this middleware from your settings and add your own version instead. Just make sure that it calls django_mobile.set_flavour at some point to set the correct flavour for you.

If you need example how tablet detection can be implemented, you can checkout the middleware.py file in directory examples. Feel free to modify it as you like!

Settings

Here is a list of settings that are used by django-mobile and can be changed in your own settings.py:

FLAVOURS

A list of available flavours for your site.

Default: ('full', 'mobile')

DEFAULT_MOBILE_FLAVOUR

The flavour which is chosen if the built-in MobileDetectionMiddleware detects a mobile browser.

Default: 'mobile'

FLAVOURS_COOKIE_HTTPONLY

The value that get passed into HttpResponse.set_cookie's httponly argument. Set this to True if you don't want the Javascript code to be able to read the flavour cookie.

Default: False

FLAVOURS_COOKIE_KEY

The cookie name that is used for storing the selected flavour in the browser. This is only used if FLAVOURS_STORAGE_BACKEND is set to 'cookie'.

Default: 'flavour'

FLAVOURS_TEMPLATE_PREFIX

This string will be prefixed to the template names when searching for flavoured templates. This is useful if you have many flavours and want to store them in a common subdirectory. Example:

from django.template.loader import render_to_string
from django_mobile import set_flavour

set_flavour('mobile')
render_to_string('index.html') # will render 'mobile/index.html'

# now add this to settings.py
FLAVOURS_TEMPLATE_PREFIX = 'flavours/'

# and try again

set_flavour('mobile')
render_to_string('index.html') # will render 'flavours/mobile/index.html'

Default: '' (empty string)

FLAVOURS_TEMPLATE_LOADERS

django-mobile's template loader can load templates prefixed with the current flavour. Specify with this setting which loaders are used to load flavoured templates.

Default: same as TEMPLATE_LOADERS setting but without 'django_mobile.loader.Loader'.

FLAVOURS_GET_PARAMETER

Users can change the flavour they want to look at with a HTTP GET parameter. This determines the name of this parameter. Set it to None to disable.

Default: 'flavour'

FLAVOURS_SESSION_KEY

The user's preference set with the GET parameter is stored in the user's session. This setting determines which session key is used to hold this information.

Default: 'flavour'

FLAVOURS_STORAGE_BACKEND

Determines how the selected flavour is stored persistently. Available values: 'session' and 'cookie'.

Default: 'cookie'

Cache Settings

Django ships with the cached template loader django.template.loaders.cached.Loader that doesn't require to fetch the template from disk every time you want to render it. However it isn't aware of django-mobile's flavours. For this purpose you can use 'django_mobile.loader.CachedLoader' as a drop-in replacement that does exactly the same django's version but takes the different flavours into account. To use it, put the following bit into your settings.py file:

TEMPLATES = [
   {
      ...
      'OPTIONS': {
         ...
         'loaders': ('django_mobile.loader.CachedLoader', (
            'django_mobile.loader.Loader',
            'django.template.loaders.filesystem.Loader',
            'django.template.loaders.app_directories.Loader',
         )),
      }
   }
]

Download Details:
Author: gregmuellegger
Source Code: https://github.com/gregmuellegger/django-mobile
License: BSD-3-Clause License

#django  #python