django中用于缓存的高级模板标记:版本控制、压缩、部分缓存、简单继承

django-adv-cache-tag的Python项目详细描述


| PYPI版本构建状态

==



-版本控制
-压缩
-部分缓存
-易于扩展/自定义

在http://documentup.com/twidi/django adv cache tag

很容易使用这个新的
one.

with``django adv cache tag``您可以:

-在您的templatetag中添加一个版本号(int、string、date或其他,它将被
字符串化):版本将与缓存的版本进行比较,并使用完全相同的缓存键新的
缓存模板,避免在缓存中保留旧的未使用密钥,
允许您永远缓存。
-避免在我们的算法中害怕不兼容的更新,
因为我们还使用内部版本号,仅在
内部算法更改时更新
-定义您自己的缓存键(或者简单地说,只需将主键(或者
您想要的,它是一个templateTag参数)添加到此缓存键
-压缩要缓存的数据,以减少
缓存后端的内存消耗,和网络延迟(但它将使用更多的时间和cpu
来压缩/解压缩,由您选择)
-选择将使用哪个缓存后端
-在您的缓存
模板中定义`{%nocache%}…{%endnocache%}`块,这些块只有在被要求时才会呈现(对于这些部分,模板的
内容被缓存,而不是呈现的结果)
-很容易定义您自己的算法,因为我们提供了一个类(带有
短方法),您可以从中继承,只需更改选项或
您想要的任何行为,并为它们定义自己的标记
-使用pypi上提供了缓存片段名称的变量


----

``django adv cache tag``安装:



1,请注意内部版本号已更改,因此所有
缓存都将重置。**


如果要支持python 2,则必须通过传递版本来安装::


或者您可以在github上找到它:
https://github.com/twidi/django adv cache tag

(对于python2版本:https://github.com/twidi/django adv cache tag/tree/python2)

安装时,只需在
您的django项目。

请参阅下一节中的示例,了解其工作原理(基本上与默认django缓存模板标记相同)


templateTag,您可以添加任意多个参数
,包括版本或日期,如果此版本发生更改,则缓存键将发生更改。因此,缓存将按预期进行更新。

但旧密钥不会被删除,如果过期时间较长,它将在那里停留很长时间,消耗宝贵的内存。

``django adv cache tag``提供了一种避免这种情况的方法,但仍
需要时重新生成缓存。为此,当激活时,我们使用传递给templateTag的
最后一个参数作为"版本号",并将其删除以用于生成缓存密钥的参数。

此版本将用于缓存模板的**内容**,
而不是**密钥**,当缓存存在并加载时,
缓存版本将与所需版本进行比较,如果两者匹配,
缓存有效并返回,否则将重新生成。

我们还管理一个内部版本号,它总是
与缓存的版本号相比较。此内部版本号仅在"django adv cache tag"的内部算法更改时更新。
但您可以通过在设置中添加"adv cache version"来更新它,使所有缓存的模板失效(我们的内部版本和此设置中的
值将是连接以获取真正使用的内部版本


如果"adv_cache_versioning"设置为true,则基于字符串"myobj主模板"和"obj.pk"的值,键将始终相同,但每次"obj.date_last_updated"更改时都将重新生成缓存的值。

`` 0``,要始终缓存模板,因为我们现在没有太多副本(旧副本和当前副本)。

代码::django

{%load adv廑cache%}
{%cache 0 myobj廑u main廑u template obj.pk obj.date廑u last廑updated%}
{{{obj}
{%endcache%}

primary key
~br/>

description
^^^^^^^^^^^

缓存键如下:
one::

:1:template.cache.your_fragment廑name.64223ccf70bbb65a3a4aceac37e21016

因此,使用
``django adv cache tag``您可以在片段名和散列名之间添加一个"主键":

:1:template.cache.your廑fragment廑name.your廑pk.64223ccf70bbb65a3a4aceac37e21016

片段
每个对象,因此我们可以使用对象主键,您可以使用任何想要的
,id,字符串…


添加主键,只需将"adv_cache_include_pk"设置设置设置为
"true",第一个参数(在片段名之后)将被用作pk。


如果您只希望缓存模板标记的一部分这样做,请阅读本自述文件后面的"扩展默认缓存标记"部分(这真的很简单)。


作为
生成缓存密钥散列的参数而保留。

代码::django

{%cache 0 myobj_main_template obj.pk obj.date_last_updated%}


compression
~~~~~~~~


description
^^^^^^^^^^^^^^

默认的django cache templatetag只是将生成的html保存在缓存中。根据您的模板,if可能是大量的html,并且您的
缓存将快速增长。更不用说,由于模板中的缩进,我们可以有很多空格(我知道有两种方法可以在不使用"django adv cache tag"的情况下删除它们:django提供的"`{%spaceless%}`
templatetag"和"django template preprocessor"<;https://github.com/citylive/django template preprocessor/>;``uuuuu.

``django adv cache tag``可以为您做到这一点。它可以通过用一个简单的空格替换掉重复的空格(包括换行符、制表符),从而删除重复的空格(保持HTML中的空格行为),并通过`` zlib```(和``pickle``)模块。

我没有对此做过任何测试,但是对于
一些模板,保存的数据可以从2 ko减少到
1。

要激活这些功能,只需将下面定义的一个或两个
设置设置设置为"true"。

警告:如果使用的缓存后端使用pickle及其默认协议,
压缩是无用的,因为二进制文件没有得到很好的处理,存储在缓存中的最终大小将大大大于压缩后的大小。所以在激活这个选项之前检查一下。默认的django后端(至少在1.4中)是可以的,但是django redis缓存不可以,等待我的请求,但是你可以检查我自己的版本:
https://github.com/twidi/django redis缓存/tree/pickle\'u版本

默认为"false",通过"zlib"激活压缩,默认为"false",激活
减少空白字符。

example
^^^^^^


no example,因为您不必更改templateTag的任何内容
调用此函数,只需设置设置即可。

但如果使用默认的缓存模板标记,则无法确定使用哪一个,它将自动成为默认的缓存模板标记。

``django adv cache tag``可以通过提供设置
``adv cache backend``来实现这一点,该设置将采用设置中定义的缓存后端名称
。并且通过扩展提供的``cachetag`
对象,您甚至可以定义许多要由许多
模板标记使用的后端,例如一个用于访问频繁的模板,另一个用于
其他模板……随你所愿。阅读``扩展默认缓存标记``部分
了解更多信息(这很简单,真的,但我已经告诉过你…

您不必对templateTag更改任何内容,只需设置设置即可。使用默认的django cache templateTag,您的模板将被缓存,并且无法在显示之前更新模板,因此,对于用户名、
当前日期或其他任何内容,不能缓存包含少量动态片段的
html的大部分。您可以欺骗并保存动态部分周围的两个模板,但您将有更多的访问
缓存后端的权限。

``django adv cache tag``允许使用一个或多个`{%nocache%}```
块(由`{%endnocache%}```关闭)来放入`{%cache%}``
块。这些`{%nocache%}`块将按原样保存在
缓存中,而其余块将呈现为html。只有当模板最终显示时,没有缓存的部分才会被渲染。


自动激活。

代码::django

{%cache 0 myobj_main_template obj.pk obj.date_last_updated%}
<;p>;这是{{{obj}模板的缓存部分,在{%now"r"%}计算。<;/p>;
{%nocache%}
<;p>;每次都将评估此部分:{%now"r"%}<;/p>;
{%endnocache%}
<;p>;这是另一个缓存部分<;/p>;
{%endcache%}


ent name是用作创建缓存键的基的名称,仅在过期后定义。


django文档声明``该名称将保持原样,不使用变量`。

未被引用的片段名
将被解析为应在上下文中的变量。

如果在上下文中有一个名为
``fragment\u name``的变量,则可以执行此操作:

…代码::django

{%cache 0 fragment_name obj.pk obj.date_last_updated%}

代码::django

{%cache 0"myobj_main_template"obj.pk obj.date_last_updated%}

你可以看到双引号,但是单引号是一样的,或者根本没有引号:

代码::django

{%cache 0"myobj_main_template"obj.pk obj.date_last_updated%}

使用不同的行为
作为默认提供的行为,您将很高兴知道
``django adv cache tag``是以易于扩展的方式编写的。

甚至还有一个"meta"类(从django模型中窃取的idea
:d)。因此很容易覆盖一个简单的
部分。

更改默认设置(全部为"false"、
并使用"default"后端),但希望激活版本控制的templatetag:

创建一个新的templatetag文件(``myapp/templatetags/my_cache_tags.py`)
,其中:

。代码::python

from adv_cache_tag.tag import cachetag


class versionedcachetag(cachetag):
class meta(cachetag.meta):
versioning=true


from django import template
register=template.library()

register(register,'ver_cache')

代码::django

{%load my_cache_tags%}
{%ver_cache 0 my obj_main_template obj.pk obj.date_last_updated%}
obj
{%endver_cache%}

只需将`{%load adv-cache%}``(或django默认值
`{%load cache%}``)替换为`{%load my-cache-tags%}``(您的templatetag
模块),将`{%cache%}` templatetag替换为新定义的`{%ver-cache%}`……%}。也不要忘记替换结束标记:
`{%endver\u cache%}`。但是`{%nocache%}`将保持不变,
除非您想要一个新的。为此,只需向
``register``方法添加一个参数:

…代码::python

mycachetag.register(register,'ver_cache','ver_nocache')

…代码::django

{%ver\u缓存…%}
缓存
{%ver nocache%}不缓存{%endvernocache%}
{%endver cache%}

请注意,如果您知道
将不会在模板中加载提供
缓存标记的另一个template tag模块,则可以保留标记的名称"cache"。为此,最简单的方法是:
mycachetag.register(register)"cache"和"nocache"是默认值

请参阅"设置"部分以查看它们。

更新模板文件时,内部版本
~~~~~~~~~~~~~~~~~~~

,使此模板的所有
缓存版本无效的唯一方法是更新传递给templateTag的片段名或
参数。

但是
如果您想使用
``django adv cache tag``的版本控制系统的功能,它可能太冗长:

……代码::django

{%load adv_cache%}
{%with template_version=obj.date_last_u updated;stringformat:"s"add:"v1"%}
{%cache 0 myobj_main_template obj.pk template_version%}

{%endcache%}
{%endwith%}

``django adv cache tag``通过设置
``adv cache version``提供了一种简单的方法。但是通过更新,**所有**缓存的
版本都将失效,而不仅仅是您更新的版本。

代码::python

class my cachetag(cachetag):
class meta(cachetag.meta):
internal_version="v1"


mycachetag.register('my_cache')

,然后在模板中,您只需执行

。代码::django

{%load my_cache_tags%}
{%my_cache 0 my obj_main_template obj.pk obj.date_last_updated%}

{%endmy_cache%}


只需更改"mycachetag"类中的"内部版本"(或
您可以为此使用设置)。


更改缓存后端
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果要更改一个templatetag的缓存后端,这很简单:

。代码::python

class mycachetag(cachetag):
class meta:
cache_backend='templates'

,但您也可以通过重写方法:

代码::python


最近的:

…代码::python

如果self.get_pk()<;1000:
cache_backend='slow_templates'
return get_cache(cache_backend)

如果它提供这两种方法,就可以满足您的需要。更重要的是,如果不想使用cache backend对象的默认"set"和"get"方法,则可以覆盖"cache tag"类的"cache set"和"cache get"方法
。使用
在最后一个参数处设置的"using"参数(在"using"和缓存后端的名称之间没有空格)。

代码::django

{%cache 0 myobj_main_template obj.pk obj.date_last_updated using=foo%}



创建缓存键:

-``get-base-cache-key``,如果
``include-pk``是'true``或
`模板,%(nodename)是'name```,则默认返回可格式化字符串
("template.%(nodename)s.%(hash)s",它返回要在前一个字符串中使用的参数,这两个字符串结合在一起,参数是:


-``nodename``参数是`` templatetag``的名称:它是`{%my cache`中的
"mycache"……%}`
-``name``是模板标记的"片段名";
expire time
-``pk``之后的值仅在``self.options.include\pk``是``true``时使用,并且``this.get\pk()``
-``hash``是片段名之后所有参数的哈希值,
排除最后一个版本号(此排除
仅当"self.options.versioning"为"true"时才会发生

如果要删除"template."部分,则在缓存键开始处
(如果缓存后端专用于模板缓存,则无用)。你可以这样做:


…代码::python

mycachetag类(cachetag):
def get_base_cache_key(self):
cache_key=super(mycachetag,self).get_base_cache_key()
return cache_key[len('template:'):]或[9:]


>将参数添加到templateTag
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

默认情况下,由"cachetag"提供的templatetag使用与默认django cache templatetag相同的
参数。

,并返回
将传递给真正的templateTag的标记,即绑定到
``cacheTag```的``node``类。

代码::python

from django import template


from adv_cache_tag.tag import cachetag,node


class mynode(node):
def_u init_u(self,node name,nodelist,expire_time,foo,fragment_u name,vary_o on):
"在节点中保存foo变量(而不是"已解决)""
超级(mynode,self)。\uu init(self,nodename,nodelist,expire\u time,fragment\u name,改变)
self.foo=foo



class mycachetag(cachetag):

node=mynode


def prepare_params(self):
"将foo变量解析为它的真实内容"
super(mycachetag,self)。prepare_params()
self.foo=template.variable(self.node.foo).resolve(self.context)

@classmethod
def get_template_node_arguments(cls,tokens):
"检查令牌的有效性,并将其返回为准备传递给节点类"
if len(tokens)<;4:
提升模板。模板语法错误(u"'%r'标记至少需要3个参数。"%tokens[0])
返回(tokens[1]、tokens[2]、tokens[3]、tokens[4:])


准备模板缓存类,但它可能很有用。当对象被更新时,最好在此时重新生成缓存的模板,而不是在需要显示它的时候。您可以通过捕捉
模型的"post\u save"信号,或者只重写其"save"方法来完成此操作。在这个例子中,我们将使用最后一个解决方案。


唯一特别的是要知道模板的路径,其中
templateTag是。在我的例子中,我有一个模板(包含在
其他模板中,供一般使用),因此很容易找到它并重新生成它,如本例中所示。我们这里没有"请求"对象,
因此上下文处理器无法工作,我们必须创建一个上下文对象
,该对象将用于呈现模板,包含所有需要的变量。

代码::python

**kwargs)

template='path/to/my_template_file_with_my_cache_block.html'

'obj':self,

"静态URL":设置。静态URL,

parts
'\u partial\uu':true,


}


loader.get\u template(template).render(context)


假设您想显示一个对象列表,但
您只有从redis中检索到的id和版本(使用``zset`,使用
id作为值,使用更新日期(用作版本)作为分数,例如



因为每次保存时都会重新生成,如上所示,
没关系,只需在
templateTag参数中添加对象的主键作为"pk",就会加载缓存的模板。

您将遇到一个问题:当django将
呈现模板时,上下文中存在的对象的唯一部分
是主键,因此如果需要名称或任何字段来呈现缓存的模板,它将不起作用。

因为我们可以从数据库加载对象并将其添加到上下文中。代码::python

def my_view(请求):
objects=[
dict(
pk=val[0],
date_last_updated=val[1]

]
返回render(request,"my_u results.html",dict(objects=objects))


模板"my_u results.html"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

。代码::django

{%for obj in objects%}
{%include"my\u result.html"%}
{%endfor%}


template"my\u result.html"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

代码::django

{%r/>{%r/>{%my-cache 0 myoybj主模板obj.pk obj.date最后一次更新的日期}
{{{{obj}
{{{obj}
{%endmy'u cache%}





templatetag
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^是的代码::python


从我的应用程序导入mymodel


class my cachetag(cachetag):

class meta(cachetag.meta):
"强制选项"
包含pk=true
版本控制=true

def创建内容(self):
"如果上下文中的对象不是真正的模型,则从db加载它。"
如果不是实例(context['obj'],myobject):
context['obj']=mymodel.objects.get(id=self.get_pk())
super(mycachetag,self).create_content()



小心点,它会将as数据库请求生成为要加载的对象。


``cache tag``类的ode(在``tag.py``中),所有方法都有文档记录。

settings
--

``django adv cache tag``提供5个可以更改的设置。下面是
列表,其中包含
``meta``类中的描述、默认值和相应字段(可通过``self.options.some_field``在
``cachetag``对象中访问)

-``adv_cache`版本控制``来激活版本控制,默认为``false`
(``meta``类中的``versioning`)
-``adv缓存压缩``激活压缩,默认为``false`
(``meta``类中的``compress`)
-``adv缓存压缩``激活空间压缩,默认
到``false`(``meta``类中的``compress`spaces`)
-``adv`cache-include`pk``激活"主键"功能,
默认到``false`(``meta``类中的``include`pk`)
-``adv`cache-backend``选择要使用的缓存后端,默认为
`"default"``(``meta``类中的`cache`backend`)
-``adv`cache`version``创建自己的内部版本(将
连接到
``django adv cache tag``的实际内部版本),默认为```(``internal_version``在``meta``类中)


代码::django

{%load adv_cache%}
{%cache…%}
foo
{%nocache%}
bar
{%endnocache%}
baz
{%endcache%}

代码::django

foo
{%endraw_xyz%}
bar
{%raw_xyz%}
baz


代码::django

{%raw{uxyz%}
foo
{%endraw{uxyz%}
bar
{%raw{uxyz%}
baz
{%endraw{uxyz%}

只是为了节省一些字节。


``{%raw xyz%}`和`{%endraw xyz%}`之间的部分根本不被解析
(被django看作是一个``textnode`)

站点。

它允许最大限度地避免与缓存版本中的解析内容发生冲突。

如果html包含其中一个字符串,那么我们的
最终模板将被破坏,因此我们使用带散列的长模板(但是我们不能100%确定这些字符串不能在缓存的html中,
但对于常见用法,它应该足够)


许可证
----

许可证文件)


运行测试
----

只要运行:


django admin test adv_cache_tag

(您可能需要使用``django admin``或`./manage.py``取决于
您的安装)

安装
所需的django版本::

pip install django

,然后在python路径中使"adv廑u cache廑u tag"模块可用。
例如,使用"virtualenv wrapper",考虑到您位于"django adv cache tag"存储库的根目录下,只需执行以下操作:

add2virtualenv.


或简单地执行以下操作:


它们是这样的:

django_settings_module=adv_cache_tag.tests.testproject.settings django-admin.py test adv_cache_tag

,或者只需启动"runtests.sh"脚本(它将运行这个精确的
命令)::

./runtests.sh

各版本









<

==================================================================================================================================================
1.8至1.10 3.4、3.51.1.1
1.11 3.4至3.11 3.4至3.11 3.4至3.11.6 1.1.1.1
>2.0 3.4至3.7 1.3.4至3.7 1.1.1.2
2.1 3.5至3.1.7 1.1.1.2
===============================


。| pypi版本image::https://img.shields.io/pypi/v/django adv cache tag.png
:目标:https://pypi.python.org/pypi/django adv cache tag
:alt:pypi版本
。|构建状态图像::https://travis ci.org/twidi/django adv cache tag.png
:目标:https://travis ci.org/twidi/django adv cache tag
:alt:travis ci上的构建状态


欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
具有parend子关系的java Save Hibernate实体失败,出现外键错误   数组如何从嵌套数组中收集结果。Java IntStream中的forEach   java替换正则表达式中的Group2   java匕首2:避免导出私有依赖项   java我怎样才能把方块放在播放器下面?   java Eclipse JDT自动格式化:不带大括号的“if”后面的缩进语句   lambda如何使用Java8流和过滤器过滤嵌套循环?   java JPA批插入不能提高性能   java时间转换为时间戳   java我添加数组奇数的方法的逻辑有什么问题   使用迭代器从Java集合中删除元素   java如何使用spring生成i18n错误   ubuntu如何在没有glassfish的情况下安装/下载JavaEE javadocs?   java一个接一个地显示SQLite列