Python の getattr() メソッドは、特定の属性の名前が事前にわからない場合に役立ちます。
この機能はテンプレートでも役立ちますが、それを行う方法がわかりませんでした。動的属性検索を実行できる組み込みタグまたは非組み込みタグはありますか?
Python の getattr() メソッドは、特定の属性の名前が事前にわからない場合に役立ちます。
この機能はテンプレートでも役立ちますが、それを行う方法がわかりませんでした。動的属性検索を実行できる組み込みタグまたは非組み込みタグはありますか?
私はそうは思わない。しかし、カスタム テンプレート タグを記述してコンテキスト dict の属性を返すことはそれほど難しくありません。単に文字列を返そうとしている場合は、次のようにしてみてください。
class GetAttrNode(template.Node):
def __init__(self, attr_name):
self.attr_name = attr_name
def render(self, context):
try:
return context[self.attr_name]
except:
# (better yet, return an exception here)
return ''
@register.tag
def get_attr(parser, token):
return GetAttrNode(token)
これは、データ内で頻繁に繰り返される条件でない限り、テンプレートではなくビューで行うのと同じくらい簡単であることに注意してください。
問題のモデルにメソッドを追加することになり、そのメソッドにはテンプレートの属性のようにアクセスできます。
それでも、組み込みのタグを使用して属性を動的に検索できるようになれば素晴らしいと思います。これは、私たちの多くがテンプレートで常に抱えている問題だからです。
get と getattr の区別を保ちながら、
@register.filter(name='get')
def get(o, index):
try:
return o[index]
except:
return settings.TEMPLATE_STRING_IF_INVALID
@register.filter(name='getattr')
def getattrfilter(o, attr):
try:
return getattr(o, attr)
except:
return settings.TEMPLATE_STRING_IF_INVALID
組み込みのタグはありませんが、独自の.
そのスニペットは私の一日を救いましたが、関係にまたがる必要があったので、「。」で引数を分割するように変更しました。そして再帰的に値を取得します。1 行で実行することもできますが
return getattribute(getattribute(value,str(arg).split(".")[0]),".".join(str(arg).split(".")[1:]))
、読みやすくするために 4 行のままにしました。誰かがこれを使ってくれることを願っています。
import re
from django import template
from django.conf import settings
numeric_test = re.compile("^\d+$")
register = template.Library()
def getattribute(value, arg):
"""Gets an attribute of an object dynamically AND recursively from a string name"""
if "." in str(arg):
firstarg = str(arg).split(".")[0]
value = getattribute(value,firstarg)
arg = ".".join(str(arg).split(".")[1:])
return getattribute(value,arg)
if hasattr(value, str(arg)):
return getattr(value, arg)
elif hasattr(value, 'has_key') and value.has_key(arg):
return value[arg]
elif numeric_test.match(str(arg)) and len(value) > int(arg):
return value[int(arg)]
else:
#return settings.TEMPLATE_STRING_IF_INVALID
return 'no attr.' + str(arg) + 'for:' + str(value)
register.filter('getattribute', getattribute)