非理性繁荣

用于谷歌分析的Django中间件(重新发布)

6月14日2007.根据丹戈

这是一种原始的非理性繁荣的移植,这本书写于2007年中期:大约两年前。

Django的部分优点在于它的设计最大限度地提高了灵活性。作为开发者,我们有很多地方可以连接到Django,这些钩子允许访问Django的大部分移动部件。Django开发人员介绍的第一个钩子是urls.py文件,我们将urls映射到我们的应用程序中。但有时Django的第二个钩子——中间件——可以为我们提供简单性方面的真正收益。在本文中,我们将首先研究如何使用googleanalyticsMiddleware将对google分析的调用注入到您的页面中,然后我们将一步一步地看看它是如何构建的。在这里(这是一个较低的GNU许可证)。

使用谷歌分析中间件

使用这个中间件非常简单。您需要将analytics.py文件放在Django路径的某个位置,您需要在settings.py文件中放置几个变量。确保该文件位于django路径中的最简单方法是将其放在django源目录中(如果您通过python setup.py安装方法安装了django,则需要将其放在site packages文件夹中)。或者在Django应用程序的文件夹中。最好将analytics.py放在中间件文件夹中,因为这样所有应用程序都可以访问它。接下来,我们需要将它添加到settings.py文件中的中间件列表中。您的settings.py文件应该如下所示(此中间件不依赖于任何其他中间件,所以它的位置并不重要):

中间件类=('django.middleware.common.commonmiddleware''django.contrib.sessions.middleware.sessionmiddleware'“django.contrib.auth.middleware.AuthenticationMiddleware”'django.middleware.doc.xviewmiddleware'“myproject.analytics.GoogleAnalyticsMiddleware”)

如果你继续把它放在django.middleware文件夹中,你会想排队

“django.middleware.analytics.GoogleAnalyticsMiddleware”

接下来,您需要将全局变量分析_id添加到settings.py文件中。它的值应该是您的谷歌分析id。

分析=“这样的”

通常你不想追踪自己的数据,为了方便有第二个,可选,您可以声明的全局变量:分析\忽略\管理。如果将该值设置为true,则为登录管理员呈现的页面将不会注入Google Analytics JavaScript(您不会扭曲结果,不必加载javascript,所有人都有美好的时光)。如果要使用它,应将其插入到settings.py文件中:

分析\忽略\管理=

如果不想禁用对管理员的跟踪,那你什么都不用做,因为默认情况下中间件会被注入到所有页面中,这是为了设置它。如果你想在不向谷歌分析发送真实数据的情况下测试它,你可以在初始化这表明您应该取消对此类测试的注释。

开发中间件

我们要做的第一件事就是 中间件API.中间件对象没有任何需要扩展的特定类,他们必须实现(至少)三种方法中的一种:

process_request(自我请求)进程视图(自我请求视图\funcview_args查看关卡)过程响应(自我请求响应)

处理请求是在Django决定要呈现的视图之前截取请求(这可以用于拒绝未经授权的用户)。Process_view用于在视图呈现之前截取视图并显示其他内容(也许,一条错误消息,或者,您可能希望在用户下次登录时向他们发送一次性消息)。处理响应用于修改将显示的内容。对于插入分析代码,过程请求正是我们需要的。

设计我们的中间件

在设计中间件时,尽可能简化它是很重要的。因为每次加载页面时都会调用这个函数,所以它应该是相当有效的。这意味着我们应该设计我们的中间件来尽可能多地进行预处理(从而避免在进程响应方法中尽可能多的开销)。 初始化方法将包含大部分思考代码。我们的逻辑 初始化方法如下:
  • 从settings.py获取Analytics_id和Analytics_ignore_admin的值。
  • 除非没有ANALYTICS_ID,预构建表示对分析的javascript调用的html。
  • 如果分析没有价值,设置process_response不做任何修改就返回响应。
  • 埃利夫分析\忽略\管理为真,设置process_response以插入分析代码,除非管理员已登录。
  • 其他的process_response应该始终注入分析代码。
我们首先需要知道的是如何从settings.py中获取信息。这是这样完成的:

django.conf进口设置身份证件=设置.分析忽略=设置.分析\忽略\管理

很简单,感谢Django团队提供的元编程魔力。接下来我们需要一个简单的函数来基于id构建html字符串。它看起来是这样的:

@staticmethoddef表单分析字符串(身份证件):返回”“””“”%(STR(身份证件))

这是将值简单地注入到Python字符串中。它使用staticmethod decorator,因为它不需要访问实例的细节(使用staticmethod decorator意味着它不会自动将self作为它的第一个参数传递)。

轻微绕道:一些支持方法

的逻辑实现之前 初始化方法,我们需要制定一些支持方法,这些方法将大大简化我们的工作,我们将制定三种支持方法,一个是将分析html注入响应(当有ANALYTICS_ID时),一个简单地返回未更改的响应(当没有ANALYTICS_ID时),最后一个是检查当前用户是否是传递给它的函数的管理员,返回未更改的函数是迄今为止最简单的,我们从那里开始吧。

def返回未更改(自我请求响应):返回响应

在响应中插入分析代码稍微复杂一些,但还是合理的。

definsert_analytics(自我请求响应):内容=响应.内容指数=内容.上面的().找到(””)如果指数=-1返回响应响应.内容=内容〔:指数]+自我.超文本标记语言+上下文[指数返回响应

我们从回应中得到内容,扫描它看它是否有一个结束的身体标签,如果是这样,我们就在它之前插入分析代码(这样分析脚本就不会减慢页面的加载时间)。不错。我们需要构建的最后一个支持功能是当前的“用户管理”?检查insert_analytics方法(只有当analytics_ignore_admin变量为真时,这两个方法才会同时出现,但我们会在我们的初始化方法(如果你想知道什么是货币,它是一个函数式编程概念,你可以看到一个解释在这里.)此代码有点混乱,但是它允许我们使用insert_analytics中的代码,不管我们是否忽略管理用户。

@staticmethoddefignore_admin(芬克):defignore_if_admin(请求响应):如果请求.用户.is_authenticated()请求.用户.是员工吗?返回响应其他的返回芬克(请求响应)返回ignore_if_admin

首先让我们注意ignore_admin是一个静态函数(它只是操作一个函数,和不与类的特定实例关联)。在ignore-admin方法中,它返回一个内部函数ignore-if-admin的副本,专门用于参数“func”。因此,返回的函数会记住'func'的值,即使它从来没有显式地将其作为参数传递(这是一个常见的函数编程习惯用法)。

返回到构造函数

既然我们已经编写了我们的支持方法,我们就可以返回并完成编写构造函数的工作。

def__init__(自我):尝试身份证件=设置.分析自我.超文本标记语言=自我.表单分析字符串(身份证件)自我.过程响应=自我.insert_analytics尝试忽略=设置.分析\忽略\管理如果忽略自我.过程响应=自我.ignore_admin(自我.过程响应)除了AttributeError通过除了AttributeError自我.过程响应=自我.返回未更改

初始化方法,我们首先尝试从设置文件中获取ID,如果失败,则将process_response设置为return_unchanged方法。否则我们返回insert_analytics方法,如果合适的话,在ignore-admin方法中进行循环。初始化相当容易理解。好东西。

远离树木

现在让我们来看看我们拼凑在一起的代码的完整性。

django.conf进口设置googleanalytics中间件(对象):def__init__(自我):'googleanalyticsMiddleware的构造函数'尝试身份证件=设置.分析自我.超文本标记语言=自我.表单分析字符串(身份证件)自我.过程响应=自我.insert_analytics尝试忽略=设置.分析\忽略\管理如果忽略自我.过程响应=自我.ignore_admin(自我.过程响应)除了AttributeError通过除了AttributeError自我.过程响应=自我.返回未更改definsert_analytics(自我请求响应):内容=响应.内容指数=内容.上面的().找到(””)如果指数=-1返回响应响应.内容=内容〔:指数]+自我.超文本标记语言+内容[指数:]返回响应def返回未更改(自我请求响应):返回响应@staticmethoddefignore_admin(芬克):defignore_if_admin(请求响应):如果请求.用户.is_authenticated()请求.用户.是员工吗?返回响应其他的返回芬克(请求响应)返回ignore_if_admin@staticmethoddef表单分析字符串(身份证件):返回”“””“”%(STR(身份证件))

总之,我们用不到50行代码(忽略空格,就像一个人总是试图提出关于行数的错误观点一样)。成绩不错。既然我们已经编写了一个中间件,下一次我们将了解基本原理,并且可以写一些更有趣的东西。记住,完整的源代码是可用的。在这里,它(与我们刚刚完成构建的代码不同)实际上包含注释。