最近学些django,练习了一下定义django tag。记录一下。
我定义了一个两个表,如下:
#models.py
class package(models.Model):
packageDetail = models.TextField()
class product(models.Model):
id = models.CharField(max_length=30,primary_key=True)
name = models.CharField(max_length=100)
其中,packageDetail字段里存储的是一组product表中的id,结构如 [ ' id1 ' , ' id2 ' ]。
views.py代码如下,功能主要是为了显示所有package内容
#views.py
def packagesIndex(request):
packages = package.objects.all()
return render_to_response('tariffManagement/packageIndex.html',locals())
然后我定义了一个模板index.html
#index.html
<table>
<tr>
<td>内容</td>
</tr>
{% for package in packages %}
<tr>
<td>
{% load testTag %}
{% getNames package.packageDetail %}
</td>
</tr>
{% endfor %}
</table>
该模板是显示package内容,内容为product的名字。因为packageDetail字段存的是一组product的id,因此我需要把它转化成相对应的name。
{% load testTag %} 这里是加载一个tag文件testTag.py。
{% getNames package.packageDetail %} ,getNames 是函数名,package.packageDetail是需要转换的值,这种格式跟一般函数调用类似。
然后开始自定义tag。我首先在该app下创建templatetags文件夹,并在该文件夹下创建__init__.py空文件和testTag.py两个文件。testTag.py里面就是自定义的tag。代码如下:
#testTag.py
from django import template
from tables import product
register = template.Library()
@register.tag(name="getNames")
def getNames(parser,token):
try:
packageStr = token.split_contents()
except ValueError:
msg = '%r tag requires a single argument' % token.split_contents()[0]
raise template.TemplateSyntaxError(msg)
return getProductName(packageStr[1])
class getProductName(template.Node):
def __init__(self, packageStr):
self.packageStr= packageStr
def render(self,context):
packageDetail=template.resolve_variable(self.packageStr, context)
productNameList = []
products = product.objects.all()
for productValue in products:
if productValue.id in packageDetail:
productNameList.append(productValue.name)
productNameStr="<br/>".join(productNameList)
return productNameStr
1、def getNames(parser,token):,paser是模板parser对象,我没有用到,token是传过来的值。
2、token.split_contents()就是按空格把传过来的值分割,但引号内的不分。
3、class getProductName(template.Node):是定义了一个类,它重新定义了输出内容,通过render()来实现。
4、packageDetail=template.resolve_variable(self.packageStr, context) 是取传过来的值
5、后面的代码就是完成找出相对应的name,并以字符串的形式返回。
功能完成了,但是还是有一些细节没搞懂,这在以后的代码中继续学习。