Update documentation

This commit finishes up the tutorial.  It also fixes the individual
service documentation and documents the service-specific / global
analytical settings and context variables.
This commit is contained in:
Joost Cassee 2011-01-29 08:04:51 +01:00
parent 3db3bf4b0e
commit 4bf0fcfcc5
14 changed files with 206 additions and 237 deletions

66
docs/features.rst Normal file
View file

@ -0,0 +1,66 @@
==========================
Features and customization
==========================
The django-analytical application sets up basic tracking without any
further configuration. This page describes extra features and ways in
which behavior can be customized.
.. _internal-ips:
Internal IP addresses
=====================
Visits by the website developers or internal users are usually not
interesting. The django-analytical will comment out the service
initialization code if the client IP address is detected as one from the
:data:`ANALYTICAL_INTERNAL_IPS` setting. The default value for this
setting is :data:`INTERNAL_IPS`.
Example::
ANALYTICAL_INTERNAL_IPS = ['192.168.1.45', '192.168.1.57']
.. note::
The template tags can only access the visitor IP address if the
HTTP request is present in the template context as the
``request`` variable. For this reason, the
:data:`ANALYTICAL_INTERNAL_IPS` setting only works if you add this
variable to the context yourself when you render the template, or
you use the ``RequestContext`` and add
``'django.core.context_processors.request'`` to the list of
context processors in the ``TEMPLATE_CONTEXT_PROCESSORS``
setting.
.. _identifying-visitors:
Identifying authenticated users
===============================
Some analytics services can track individual users. If the visitor is
logged in through the standard Django authentication system and the
current user is accessible in the template context, the username can be
passed to the analytics services that support identifying users. This
feature is configured by the :data:`ANALYTICAL_AUTO_IDENTIFY` setting
and is enabled by default. To disable::
ANALYTICAL_AUTO_IDENTIFY = False
.. note::
The template tags can only access the visitor username if the
Django user is present in the template context either as the
``user`` variable, or as an attribute on the HTTP request in the
``request`` variable. Use a
:class:`~django.template.RequestContext` to render your
templates and add
``'django.contrib.auth.context_processors.auth'`` or
``'django.core.context_processors.request'`` to the list of
context processors in the :data:`TEMPLATE_CONTEXT_PROCESSORS`
setting. (The first of these is added by default.)
Alternatively, add one of the variables to the context yourself
when you render the template.

View file

@ -38,6 +38,7 @@ Contents
tutorial
install
features
services
settings
history
@ -53,9 +54,8 @@ the `GitHub project page`_:
* Use the `issue tracker`_ to discuss bugs and features.
* If you want to do the work yourself, great! Clone the repository, make
changes and send a pull request. Please create a new issue first so
that we can discuss it, and keep people from stepping on each others
toes.
changes and send a pull request. Please create a new issue to discuss
it first, and to keep people from stepping on each others toes.
* Of course, you can always send ideas and patches to joost@cassee.net.
.. _`GitHub project page`: http://github.com/jcassee/django-analytical

View file

@ -10,7 +10,7 @@ configuring the services you use in the project settings.
#. `Installing the Python package`_
#. `Installing the Django application`_
#. `Adding the template tags to the base template`_
#. `Configuring the application`_
#. `Enabling the services`_
.. _installing-the-package:
@ -85,29 +85,19 @@ base template should look like this::
</body>
</html>
Instead of using the general-purpose tags, you can also just use the
tags for the analytics service(s) you are using. See :ref:`services`
for documentation on using individual services.
Instead of using the generic tags, you can also just use tags specific
for the analytics service(s) you are using. See :ref:`services` for
documentation on using individual services.
.. _configuration:
.. _enabling-services:
Configuring the application
===========================
Enabling the services
=====================
Without configuration, the template tags all render the empty string.
You must enable at least one service, and optionally configure other
django-analytical features.
Enabling services
-----------------
By default, only configured analytics services are installed by the
template tags. You can also use the :data:`ANALYTICAL_SERVICES` setting
to specify the used services explicitly. Services are configured in the
project ``settings.py`` file. The settings required to enable each
service are listed here. See the service documentation for details.
Services are configured in the project ``settings.py`` file. The
settings required to enable each service are listed here:
* :doc:`Chartbeat <services/chartbeat>`::
@ -125,6 +115,11 @@ service are listed here. See the service documentation for details.
GOOGLE_ANALYTICS_PROPERTY_ID = 'UA-1234567-8'
* :doc:`HubSpot <services/hubspot>`::
HUBSPOT_PORTAL_ID = '1234'
HUBSPOT_DOMAIN = 'somedomain.web101.hubspot.com'
* :doc:`KISSinsights <services/kiss_insights>`::
KISS_INSIGHTS_ACCOUNT_NUMBER = '12345'
@ -143,14 +138,8 @@ service are listed here. See the service documentation for details.
OPTIMIZELY_ACCOUNT_NUMBER = '1234567'
Configuring behavior
--------------------
----
By default, django-analytical will comment out the service
initialization code if the client IP address is detected as one from the
:data:`ANALYTICAL_INTERNAL_IPS` setting, which is set to
:data:`INTERNAL_IPS` by default.
Also, if the visitor is a logged in user and the user is accessible in
the template context, the username is passed to the analytics services
that support identifying users. See :data:`ANALYTICAL_AUTO_IDENTIFY`.
The django-analytics application is now set-up to track visitors. For
information about further configuration and customization, see
:doc:`features`.

View file

@ -12,23 +12,13 @@ slows to a crawl.
.. chartbeat-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`chartbeat-configuration`.
In order to use the template tags, you need to add :mod:`analytical`
to the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The Chartbeat tracking code is inserted into templates using template
tags. At the top of the template, load the :mod:`chartbeat` template
tag library. Then insert the :ttag:`chartbeat_top` tag at the top of
@ -50,6 +40,7 @@ Because these tags are used to measure page loading time, it is
important to place them as close as possible to the start and end of the
document.
.. _chartbeat-configuration:
Configuration
@ -87,9 +78,11 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`CHARTBEAT_INTERNAL_IPS` setting,
the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
.. _chartbeat-domain:

View file

@ -12,23 +12,13 @@ designed to be very easy to use.
.. clicky-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`clicky-configuration`.
In order to use the template tag, you need to add
:mod:`analytical` to the installed applications list in the
project :file:`settings.py` file::
INSTALLED_APPS = [
...
'analytical',
...
]
The Clicky tracking code is inserted into templates using a template
tag. Load the :mod:`clicky` template tag library and insert the
:ttag:`clicky` tag. Because every page that you want to track must
@ -74,9 +64,11 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`CLICKY_INTERNAL_IPS` setting,
the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
.. _clicky-custom-data:
@ -128,10 +120,6 @@ Context variable Clicky property Description
Clicky. Default is the HTML title.
================== =============== ===================================
By default, the username of an authenticated user is passed to Clicky
automatically in the session_ property, unless that property was set
explicitly. See :data:`ANALYTICAL_AUTO_IDENTIFY`.
.. _`customized tracking`: http://getclicky.com/help/customization
.. _session: http://getclicky.com/help/customization#session
.. _goal: http://getclicky.com/help/customization#goal
@ -139,6 +127,16 @@ explicitly. See :data:`ANALYTICAL_AUTO_IDENTIFY`.
.. _title: http://getclicky.com/help/customization#title
.. _clicky-identify-user:
Identifying authenticated users
-------------------------------
If you have not set the session_ property explicitly, the username of an
authenticated user is passed to Clicky automatically. See
:ref:`identifying-visitors`.
----
Thanks go to Clicky for their support with the development of this

View file

@ -11,23 +11,13 @@ web pages that are most important to your visitors.
.. crazy-egg-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`crazy-egg-configuration`.
In order to use the template tag, you need to add :mod:`analytical` to
the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The Crazy Egg tracking code is inserted into templates using a template
tag. Load the :mod:`crazy_egg` template tag library and insert the
:ttag:`crazy_egg` tag. Because every page that you want to track must
@ -76,9 +66,11 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`CRAZY_EGG_INTERNAL_IPS` setting,
the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
.. _crazy-egg-uservars:

View file

@ -12,23 +12,13 @@ features.
.. google-analytics-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`google-analytics-configuration`.
In order to use the template tag, you need to add :mod:`analytical` to
the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The Google Analytics tracking code is inserted into templates using a
template tag. Load the :mod:`google_analytics` template tag library and
insert the :ttag:`google_analytics` tag. Because every page that you
@ -77,9 +67,11 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`GOOGLE_ANALYTICS_INTERNAL_IPS`
setting, the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
.. _google-analytics-custom-variables:

View file

@ -11,23 +11,13 @@ tracking on your website to measure effect of your marketing efforts.
.. hubspot-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`hubspot-configuration`.
In order to use the template tag, you need to add :mod:`analytical` to
the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The HubSpot tracking code is inserted into templates using a template
tag. Load the :mod:`hubspot` template tag library and insert the
:ttag:`hubspot` tag. Because every page that you want to track must
@ -77,6 +67,8 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`HUBSPOT_INTERNAL_IPS` setting,
the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.

View file

@ -11,23 +11,13 @@ the targeted, actionable feedback you need to make your site better.
.. kiss-insights-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`kiss-insights-configuration`.
In order to use the template tag, you need to add :mod:`analytical` to
the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The KISSinsights survey code is inserted into templates using a template
tag. Load the :mod:`kiss_insights` template tag library and insert the
:ttag:`kiss_insights` tag. Because every page that you want to track
@ -83,13 +73,14 @@ Identifying authenticated users
If your websites identifies visitors, you can pass this information on
to KISSinsights so that you can tie survey submissions to customers.
By default, the username of an authenticated user is passed to
KISSinsights automatically. See :data:`ANALYTICAL_AUTO_IDENTIFY` for
important information about detecting authenticated visitors.
KISSinsights automatically. See :ref:`identifying-visitors`.
You can also send the visitor identity yourself by adding the
``analytical_identity`` variable to the template context::
You can also send the visitor identity yourself by adding either the
``kiss_insights_identity`` or the ``analytical_identity`` variable to
the template context. If both variables are set, the former takes
precedence. For example::
context = RequestContext({'analytical_identity': identity})
context = RequestContext({'kiss_insights_identity': identity})
return some_template.render(context)
If you can derive the identity from the HTTP request, you can also use
@ -98,7 +89,7 @@ a context processor that you add to the
def identify(request):
try:
return {'analytical_identity': request.user.email}
return {'kiss_insights_identity': request.user.email}
except AttributeError:
return {}

View file

@ -12,23 +12,13 @@ many drop out at each stage.
.. kiss-metrics-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`kiss-metrics-configuration`.
In order to use the template tag, you need to add :mod:`analytical` to
the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The KISSmetrics Javascript code is inserted into templates using a
template tag. Load the :mod:`kiss_metrics` template tag library and
insert the :ttag:`kiss_metrics` tag. Because every page that you want
@ -74,9 +64,11 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`KISS_METRICS_INTERNAL_IPS`
setting, the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
.. _kiss-metrics-identify-user:
@ -87,13 +79,14 @@ Identifying users
If your websites identifies visitors, you can pass this information on
to KISSmetrics so that you can tie events to users. By default, the
username of an authenticated user is passed to KISSmetrics
automatically. See :data:`ANALYTICAL_AUTO_IDENTIFY` for important
information about detecting authenticated visitors.
automatically. See :ref:`identifying-visitors`.
You can also send the visitor identity yourself by adding the
``analytical_identity`` variable to the template context::
You can also send the visitor identity yourself by adding either the
``kiss_metrics_identity`` or the ``analytical_identity`` variable to the
template context. If both variables are set, the former takes
precedence. For example::
context = RequestContext({'analytical_identity': identity})
context = RequestContext({'kiss_metrics_identity': identity})
return some_template.render(context)
If you can derive the identity from the HTTP request, you can also use
@ -102,7 +95,7 @@ a context processor that you add to the
def identify(request):
try:
return {'analytical_identity': request.user.email}
return {'kiss_metrics_identity': request.user.email}
except AttributeError:
return {}

View file

@ -11,23 +11,13 @@ analysis of visitor retention or funnels.
.. mixpanel-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`mixpanel-configuration`.
In order to use the template tag, you need to add :mod:`analyticals` to
the installed applications list in the project :file:`settings.py`
file::
INSTALLED_APPS = [
...
'analytical',
...
]
The Mixpanel Javascript code is inserted into templates using a
template tag. Load the :mod:`mixpanel` template tag library and
insert the :ttag:`mixpanel` tag. Because every page that you want
@ -73,9 +63,11 @@ Internal IP addresses
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`MIXPANEL_INTERNAL_IPS` setting,
the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.
.. _mixpanel-identify-user:
@ -86,13 +78,14 @@ Identifying users
If your websites identifies visitors, you can pass this information on
to Mixpanel so that you can tie events to users. By default, the
username of an authenticated user is passed to Mixpanel automatically.
See :data:`ANALYTICAL_AUTO_IDENTIFY` for important information about
detecting authenticated visitors.
See :ref:`identifying-visitors`.
You can also send the visitor identity yourself by adding the
``analytical_identity`` variable to the template context::
You can also send the visitor identity yourself by adding either the
``mixpanel_identity`` or the ``analytical_identity`` variable to the
template context. If both variables are set, the former takes
precedence. For example::
context = RequestContext({'analytical_identity': identity})
context = RequestContext({'mixpanel_identity': identity})
return some_template.render(context)
If you can derive the identity from the HTTP request, you can also use
@ -101,7 +94,7 @@ a context processor that you add to the
def identify(request):
try:
return {'analytical_identity': request.user.email}
return {'mixpanel_identity': request.user.email}
except AttributeError:
return {}

View file

@ -12,23 +12,13 @@ retention and sales.
.. optimizely-installation:
Installation
============
Adding the template tags
========================
You only need to do perform these steps if you are not using the
generic :ttag:`analytical.*` tags. If you are, skip to
:ref:`optimizely-configuration`.
In order to use the template tag, you need to add
:mod:`analytical.optimizely` to the installed applications list in the
project :file:`settings.py` file::
INSTALLED_APPS = [
...
'analytical.optimizely',
...
]
The Optimizely Javascript code is inserted into templates using a
template tag. Load the :mod:`mixpanel` template tag library and insert
the :ttag:`optimizely` tag. Because every page that you want to track
@ -79,8 +69,10 @@ rendered.
Internal IP addresses
---------------------
Usually you do not want to use A/B testing on your development or
Usually you do not want to track clicks from your development or
internal IP addresses. By default, if the tags detect that the client
comes from any address in the :const:`INTERNAL_IPS` setting, the
tracking code is commented out. See :const:`ANALYTICAL_INTERNAL_IPS`
for important information about detecting the visitor IP address.
comes from any address in the :const:`OPTIMIZELY_INTERNAL_IPS` setting,
the tracking code is commented out. It takes the value of
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
important information about detecting the visitor IP address.

View file

@ -1,5 +1,3 @@
.. _identifying-visitors:
========
Settings
========
@ -13,22 +11,8 @@ their default values.
Default: ``True``
Automatically identify logged in users by their username.
.. note::
The template tags can only access the visitor username if the
Django user is present in the template context either as the
``user`` variable, or as an attribute on the HTTP request in the
``request`` variable. Use a
:class:`~django.template.RequestContext` to render your
templates and add
``'django.contrib.auth.context_processors.auth'`` or
``'django.core.context_processors.request'`` to the list of
context processors in the :data:`TEMPLATE_CONTEXT_PROCESSORS`
setting. (The first of these is added by default.)
Alternatively, add one of the variables to the context yourself
when you render the template.
Automatically identify logged in users by their username. See
:ref:`identifying-visitors`.
.. data:: ANALYTICAL_INTERNAL_IPS
@ -36,20 +20,5 @@ their default values.
Default: :data:`INTERNAL_IPS`
A list or tuple of internal IP addresses. Tracking code will be
commented out for visitors from any of these addresses.
Example::
ANALYTICAL_INTERNAL_IPS = ['192.168.1.45', '192.168.1.57']
.. note::
The template tags can only access the visitor IP address if the
HTTP request is present in the template context as the
``request`` variable. For this reason, the
:data:`ANALYTICAL_INTERNAL_IPS` settings only works if you add
this variable to the context yourself when you render the
template, or you use the ``RequestContext`` and add
``'django.core.context_processors.request'`` to the list of
context processors in the ``TEMPLATE_CONTEXT_PROCESSORS``
setting.
commented out for visitors from any of these addresses. See
:ref:`internal-ips`.

View file

@ -5,11 +5,15 @@ Tutorial
========
In this tutorial you will learn how to install and configure
django-analytical for basic tracking. Suppose you want to use two
different analytics services on your Django website:
django-analytical for basic tracking. Suppose your Django website
provides information about the IPv4 to IPv6 transition. Visitors
can discuss their problems and help each other make the necessary
changes to their network infrastructure. You want to use two
different analytics services:
* :doc:`Clicky <services/clicky>` for detailed traffic analysis
* :doc:`Crazy Egg <services/crazy_egg>` to see where visitors click on your pages
* :doc:`Crazy Egg <services/crazy_egg>` to see where visitors click on
your pages
At the end of this tutorial, the project will track visitors on both
Clicky and Crazy Egg, identify authenticated users and add extra
@ -74,14 +78,17 @@ changes, both Clicky and Crazy Egg will be tracking your visitors.
Identifying authenticated users
===============================
Some analytics services, such as Clicky, can identify and track
individual visitors. If django-analytical tags detect that the current
user is authenticated, they will automatically include code to send the
username to services that support this feature. This only works if the
template context has the current user in the ``user`` or
``request.user`` context variable. If you use a
:class:`~django.template.RequestContext` to render templates (which is
recommended anyway) and have the
When you visitors post questions on IPv6 or tell about their experience
with transitioning, they first log in through the standard Django
authentication system. Clicky can identify and track individual
visitors and you want to use this feature.
If django-analytical template tags detect that the current user is
authenticated, they will automatically include code to send the username
to services that support this feature. This only works if the template
context has the current user in the ``user`` or ``request.user`` context
variable. If you use a :class:`~django.template.RequestContext` to
render templates (which is recommended anyway) and have the
:class:`django.contrib.auth.context_processors.auth` context processor
in the :data:`TEMPLATE_CONTEXT_PROCESSORS` setting (which is default),
then this identification works without having to make any changes.
@ -93,10 +100,12 @@ disable or override it, see :ref:`identifying-visitors`.
Adding custom tracking data
===========================
You want to track whether visitors are using IPv4 or IPv6. (Maybe you
are running a website on the IPv6 transition?) This means including
the visitor IP protocol version as custom data with the tracking code.
The easiest way to do this is by using a context processor::
You think that visitors who already use IPv6 use the website in a
different way from those still on IPv4. You want to test this by
segmenting the Crazy Egg heatmaps based on the IP protocol version. You
need to including the visitor IP protocol version with the Crazy Egg
tracking code. The easiest way to do this is by using a context
processor::
def track_ip_proto(request):
addr = request.META.get('HTTP_X_FORWARDED_FOR', '')