最近学些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,并以字符串的形式返回。
功能完成了,但是还是有一些细节没搞懂,这在以后的代码中继续学习。