9

情况

我正在编写一个检查 Django 模板的检查程序。例如,我想检查是否所有使用url模板标签的 Django 模板,在第一个参数上使用引号,以便它与 Django 1.5 兼容。我还想检查他们是否已包含{% load url from future %}在他们的模板中。

例如,如果我的程序解析以下 Django 模板,我希望它引发异常。

{% extends 'base.html' %}
<td>
  <a href="{% url first second %}">
  </a>
</td>

但是这个模板应该毫无例外地被解析。

{% extends 'base.html' %}
{% load url from future %}
<td>
  <a href="{% url 'first' second %}">
  </a>
</td>

我不限于这个简单的例子。我还有其他解析要做。例如,我想检查模板中存在多少load模板标签。

问题

我怎样才能优雅地解决这个解析问题?

  • 我不想使用正则表达式。
  • 我这个 Django 它自己在这方面有一些实用程序。我认为使用它们是一个好主意,但我不知道如何。
  • 我想与 Django 分开运行该程序。所以我不希望 Django 自己运行程序(使用render_to_response)。(这很重要

代码

请告诉我一些可以解决我提到的示例的代码。我想检测是否{% load url from future %}在代码中。另外我想检查每个url模板标签并检查第一个参数是否被引用。

奖金

  • 我希望能够看到 Django 从此模板生成的渲染 HTML,并对其进行 HTML 解析。(例如使用 PyQuery)
4

3 回答 3

9

你说...

我想检查是否所有使用 url 模板标记的 Django 模板,在第一个参数上使用引号,以便它与 Django 1.5 兼容。

...和...

我不想使用正则表达式。

...因为...

结果可能会变成一个巨大的意大利面条代码

...但是,坦率地说,从头开始编写解析器可能比使用正则表达式更加混乱。我看不出像这样简单的正则表达式有什么乱七八糟的......

"{% *url +[^']"

...而且我怀疑是否有一种基于非正则表达式的解决方案会如此简洁。

关于...

我还想检查他们是否已包含 {% load url from future %}在他们的模板中。

如果您的目的是确保 Django 1.5 的兼容性,那么这是没有意义的。根据Django 1.5 发布说明,新式 url 标签语法默认启用,因此该行{% load url from future %}不会有任何效果。

在 1.5 之前的版本中,只需将...

import django.template
django.template.add_to_builtins('django.templatetags.future')

...at the bottom of your settings.py and be done with it. :-)

于 2013-04-11T18:38:18.533 回答
4

You can also use the compile_string method.

 >>> from django.template.base import *
 >>> settings.configure()
 >>> compile_string("<a href='ab'></a>{% cycle 'row1' 'row2' as rowcolors %}", None)
 >>> [<Text Node: '<a href='ab'></a>'>, <django.template.defaulttags.CycleNode object at 0x10511b210>]

The compile string method is utilized by the Template class and is the method used to produce the node list. Tested in Django 1.8 Alpha.

https://github.com/django/django/blob/1f8bb95cc2286a882e0f7a4692f77b285d811d11/django/template/base.py

于 2014-07-05T04:33:46.723 回答
3

Next code still uses django, but it can check if syntax is correct:

>>> from django.template import Template
>>> from django.template.defaulttags import URLNode
>>> t = Template("{% load url from future %}\n{% url projects_list company.slug %}")
>>> for node in t.nodelist:
...     if isinstance(node, URLNode):
...         for arg in node.args: print(arg)
... 
company.slug
>>> t2 = Template('{% load url from future %}\n{% url "projects_list" company.slug }')
>>> for node in t2.nodelist:
...     print(node)
... 
<django.template.defaulttags.LoadNode object at 0x32145d0>
<Text Node: '
{% url "projects_list" c'>
>>> 

As you see last node is not URLNode

于 2013-04-15T17:24:18.170 回答