Search code examples
javascriptdjangodjango-template-filters

django template tag not getting invoked more than once in javascript function


In my django application, I have created a template tag function that generates a random number that I am assigning as random IDs to programmatically generated elements.

 import os
 import random
 from django import template

 register = template.Library()

 @register.tag(name="randomgen")
 def randomgen(parser, token):
     items = []
     bits = token.split_contents()
     for item in bits:
         items.append(item)
     return RandomgenNode(items[1:])

 class RandomgenNode(template.Node):
    def __init__(self, items):
       self.items = []
       for item in items:
          self.items.append(item)

    def render(self, context):
        arg1 = self.items[0]
        arg2 = self.items[1]
        if "hash" in self.items:
            result = os.urandom(16).encode('hex')
        elif "float" in self.items:
            result = random.uniform(int(arg1), int(arg2))
        elif not self.items:
            result = random.random()
        else:
            result = random.randint(int(arg1), int(arg2))
        return result

In my html template, I have used the load tag to import the template tag .py file:

{% load custom_tag %}

On a particular button click, the randomgen() function is invoked only once:

$(document).on("click", ".add_div_btn", function() {
     let random_id = "{% randomgen 100 1000 %}";
     <!-- will generate a random number between 10 and 100 -->
     console.log("random id: ", random_id);
});

However, every button click after the first one generates the same number.

On checking the console log, i found out that the randomgen() function within the custom_tag.py file was getting called only once.

I am unsure how to make a proper invocation call to the django template tag function in javascript.


Solution

  • JavaScript is run in the frontend and Django template tags are run on the server.

    The JavaScript in your template ends up being rendered as (e.g.)

    $(document).on("click", ".add_div_btn", function() {
         let random_id = "477";
         <!-- will generate a random number between 10 and 100 -->
         console.log("random id: ", random_id);
    });
    

    so of course it will always print the same ID.

    If you really, really need to generate the random ID server-side, you would need to do an AJAX/fetch call to an API endpoint on the server... but what you really probably want is

    $(document).on("click", ".add_div_btn", function() {
         let random_id = Math.floor(100 + Math.random() * (1000 - 100));
         // will generate a random number between 10 and 1000
         console.log("random id: ", random_id);
    });
    

    and no custom template tag at all.