Home:ALL Converter>How to use method parameters in a Django template?

How to use method parameters in a Django template?

Ask Time:2009-10-07T12:58:39         Author:orokusaki

Json Formatter

I know there is a post here: django template system, calling a function inside a model describing how you can make a custom template filter to achieve this, but from a programmer's standpoint this is a failure because that's hacking something that isn't meant for that. It seems almost ridiculous that you can't call a method with parameters in Django's template system.

Author:orokusaki,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/1529550/how-to-use-method-parameters-in-a-django-template
tghw :

The Django team has decided, as a matter of philosophy, not to allow passing method parameters in a view. Personally, I agree with them; it forces a separation of logic and presentation that I find helpful. It prevents the kind of spaghetti code that PHP is notorious for.\n\nThe right thing to do in the case you linked is to pass the result of that call from the view into the template via the context. It's just more maintainable that way. If later you need to change my_related_deltas(3) to my_related_deltas(4), you go to the view, which should be fairly concise, instead of searching through templates to figure out exactly where it is defined.",
2009-10-07T05:15:31
seler :

Despite django authors suggest not to feed our methods with arguments you can still do that using this 'little' template tag I wrote. \n\nIn my example I'm just showing that this is possible. For security reasons I strongly recommend you to write templatetags instead of trying to pass arguments to model methods.\n\n!WARNING! this is for testing purpose only! By using this you might be able to hack into NASA as well as you may got killed. \n\nclass CallNode(template.Node):\n def __init__(self,object, method, args=None, kwargs=None, context_name=None):\n self.object = template.Variable(object)\n self.method = method\n if args:\n self.args = []\n for arg in args:\n self.args.append(template.Variable(arg))\n else:\n self.args = None\n\n if kwargs:\n self.kwargs = {}\n for key in kwargs:\n self.kwargs[key] = template.Variable(kwargs[key])\n else:\n self.kwargs = None\n\n self.context_name = context_name\n\n def render(self, context):\n object = self.object.resolve(context)\n if isinstance(object, str):\n raise template.TemplateSyntaxError('Given object is string (\"%s\") of length %d' \n % (object, len(object)))\n\n args = []\n kwargs = {}\n if self.args:\n for arg in self.args:\n args.append(arg.resolve(context))\n if self.kwargs:\n for key in self.kwargs:\n kwargs[key] = self.kwargs[key].resolve(context)\n\n method = getattr(object, self.method, None)\n\n if method:\n if hasattr(method, '__call__'): \n result = method(*args, **kwargs)\n else:\n result = method\n if self.context_name:\n context[self.context_name] = result\n return ''\n else:\n if not result == None: \n return result\n else:\n return ''\n else:\n raise template.TemplateSyntaxError('Model %s doesn\\'t have method \"%s\"' \n % (object._meta.object_name, self.method))\n\n\[email protected]\ndef call(parser, token):\n \"\"\"\n Passes given arguments to given method and returns result\n\n Syntax::\n\n {% call <object>[.<foreignobject>].<method or attribute> [with <*args> <**kwargs>] [as <context_name>] %}\n\n Example usage::\n\n {% call article.__unicode__ %}\n {% call article.get_absolute_url as article_url %}\n {% call article.is_visible with user %}\n {% call article.get_related with tag 5 as related_articles %}\n\n {% call object.foreign_object.test with other_object \"some text\" 123 article=article text=\"some text\" number=123 as test %} \n \"\"\"\n\n bits = token.split_contents()\n syntax_message = (\"%(tag_name)s expects a syntax of %(tag_name)s \"\n \"<object>.<method or attribute> [with <*args> <**kwargs>] [as <context_name>]\" %\n dict(tag_name=bits[0]))\n\n temp = bits[1].split('.')\n method = temp[-1]\n object = '.'.join(temp[:-1])\n\n # Must have at least 2 bits in the tag\n if len(bits) > 2:\n try:\n as_pos = bits.index('as')\n except ValueError:\n as_pos = None\n try:\n with_pos = bits.index('with')\n except ValueError:\n with_pos = None\n\n if as_pos:\n context_name = bits[as_pos+1]\n else:\n context_name = None\n\n if with_pos:\n if as_pos:\n bargs = bits[with_pos+1:as_pos]\n else:\n bargs = bits[with_pos+1:]\n else:\n bargs = []\n\n args = []\n kwargs = {}\n\n if bargs:\n for barg in bargs:\n t = barg.split('=')\n if len(t) > 1:\n kwargs[t[0]] = t[1]\n else:\n args.append(t[0])\n\n return CallNode(object, method, args=args, kwargs=kwargs, context_name=context_name)\n elif len(bits) == 2:\n return CallNode(object, method)\n else:\n raise template.TemplateSyntaxError(syntax_message)\n",
2011-08-21T21:05:22
yy