0

The question is partially related to this one here. In addition it should be noted that the notation used below is no safe. For more details see this blog post.


I have a Django project that references multiple JS files. Initial the contents of those files were in the HTML but it slowly became too cluttered.

The problem is that inside these files I am referencing image files, which are used for creating button elements (in my case easyButton instances from Leaflet).

I am looking for a way to somehow fix these references. Note that I have called collectstatic and my HTML is using {% load static %} to load the static content. My JS files are also defined as Django template language variables themselves.

I am thinking of perhaps at least loading all the references to the static files inside the HTML and then using those inside my JS files.

Here is an example code:

{% load static %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="Content-Type" content="text/application/html; charset=iso-8859-1">
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />

        <link rel="shortcut icon" href="#" />
        <title>Test</title>
    </head>
    <body>
        ...
    </body>
</html>
<script>
    const TEST = {{ test }}; // The 'test' variable unwraps as "/home/user/.../img_default.png"
</script>
<!-- Try to use TEST inside setup.js -->
<script src="{% static 'setup.js' %}></script>
<script src="{% static 'main.js' %}></script>

where setup.js consists of function declarations that are called inside main.js, e.g.:

function add_misc_buttons() {
    var btn_create_log = L.easyButton("<img src='" + TEST + "' style='width: 32px; height: 32px;'/>", function (btn, map) {
        console.log("TODO Send debug information to the developer");

        window.location.href = "mailto:admin@example.com?body=THIS%20IS%20A%20TEST";
    });

    ...
}

with TEST being passed from the HTML file and populated by Django (a typical value would be something like images/some_image.png).

Needless to say this doesn't work. My main.js (where all the functions are called) doesn't really detect the existence of TEST. I even added a console log message to display the value but nothing shows. Is there some way to do this? I am no JS and Django expert by far. I know that variables in general are visible between tags (if declared in a correct order). But it appears this does not apply when using a mix.

rbaleksandar
  • 8,713
  • 7
  • 76
  • 161

1 Answers1

0

So not 100% sure if this will solve your issue -- but this is how I handle such setups:

# views.py

def render_post(request, id):

    # Get a qs and serialize
    qs_quotes_set = DailyQuotes.objects.all()
    qs_quotes = serializers.serialize("json", qs_quotes_set)

    # Create context
    ctx = {
        'qs_quotes': qs_quotes,
    }
    return render(request, 'board/post.html', ctx)
# post.html

...

<!-- Construct js object for daily quotes data -->

<script type="text/javascript">
 let daily_quotes = JSON.parse('{{ qs_quotes | safe }}')
</script>

...

# xy.js

for (const [key, value] of Object.entries(daily_quotes)) {

  console.log('I am an entry of your Django queryset processed in the javascript file')
}

Note that in your html file the js object constructor needs to be before the js file that should use it. Also If I recall correctly there is a small section about this topic somewhere in the Django docs but can't seem to find it right now.

JSRB
  • 2,492
  • 1
  • 17
  • 48
  • Is there a solution where no `queryset` is used? The data (icons) is not and imho doesn't make sense to be stored as a database entries. Do you have an alternative solution? (this one can also be left here since it is helpful in some situations). Even if I replace your `queryset` with a normal JSON string (visible in the HTML), I still cannot get it passed onto the JS file. I even wrote a simple function that is called inside a `` tag, while being defined inside a preceding JS file. I am missing some general knowledge on how JS inside tag interacts with JS inside separate file – rbaleksandar Feb 25 '23 at 14:42