1

I'm using django 1.9 and python 3. My english also isn't the best, so excuse the question if it is formulated bad.

I'm working on making my website a single-page application. I need to get the {% block %} contents of a given template, and then send that as a HttpResponse so that ajax can pick it up and inject it into the page.

I've tried using the answer from this question: Django - how to get the contents of a {% block %} tag from a template

But upon trying to fetch the contents of a block in my view like so:

response_data[content] = get_block_source('profile/login.html', 'content')
        
        if request.is_ajax():
            return HttpResponse(
                json.dumps(response_data),
                content_type="application/json"
            )

I just get this error from django, no matter what I do:

ValueError at /login/ Template block content not found

The contents of the block don't even make it to the ajax call, what gives?

EDIT:

I'll include my "content" block here:

in my template:

{% extends 'base.html' %}
{% block content %}
<div class="big-title text">Log in</div>
<div class="form-container">
    <form name="login-form" id="user" method="post" action="/login/" enctype="multipart/form-data" class="text">
        {% csrf_token %}
        <div class="title">Enter your credentials</div>
        <div class="form-row">
            <div class="form-flex">
                <div class="field-container">
                    <div class="field-input-container">
                        <div class="field-label accent">Username</div>
                        <div class="field-input">
                            <input class="field-input-element" type="text" name="username" />
                        </div>
                    </div>
                    <div class="field-help">Your username is always lowercase.</div>
                </div>
            </div>
            <div class="form-flex">
                <div class="field-container" style="height: 110px">
                    <div class="field-input-container">
                        <div class="field-label accent">Password</div>
                        <div class="field-input">
                            <input class="field-input-element" type="password" name="password" />
                        </div>
                    </div>
                    <div class="field-help"></div>
                </div>
            </div>
        </div>
        <div class="form-button-container">
    <div class="form-error"></div>
    <div class="form-message"></div>
    <input type="submit" name="submit" value="Accept" class="button form-button"/>
    </div>
    </form>
</div>
{% endblock %}

In my base (base.html)

<body>
    <div id="modal-container">
        <div id="modal-overlay">
            <div id="modal-items">
            </div>
        </div>
    </div>
    <div id="wrapper">
        <header>
            <div id="header-title" class="text accent">App name</div>
            <div id="header-nav">
                <nav>
                    {% if user.is_authenticated %}
                    <a href="/" class="text accent">Home</a>
                    <a href="/feed" class="text accent">Feed</a> {% if request.user.is_superuser %}
                    <a href="/admin" class="text accent">Admin</a> {% endif %}
                    <a href="" class="text">N</a>
                    <a href="/{{ request.user }}" class="header-avatar-small-a">
                        <div class="text header-greeting">Hi, {{ user.userprofile.display_name }}</div>
                        <div class="header-avatar-small">
                            {% if not user.userprofile.avatar == '' %}
                            <img src="{{ MEDIA_URL }}users/{{ user }}/avatar" alt=""> {% else %}
                            <img src="{{ MEDIA_URL }}users/avatar" alt=""> {% endif %}
                        </div>
                    </a>
                    {% else %}
                    <a href="/login" class="text accent">Log in</a>
                    <a href="/register" class="text accent">Create account</a> {% endif %}
                </nav>
            </div>
            <div class="progress">
                <div id="header-progress" class="fill"></div>
            </div>
        </header>
        <main>
            {% block content %} {% endblock %}
        </main>
        <footer></footer>
    </div>
</body>
</html>
Community
  • 1
  • 1
Sebastian Olsen
  • 10,318
  • 9
  • 46
  • 91

1 Answers1

0

Template source is the template actual HTML, not the file reference

Aviah Laor
  • 3,620
  • 2
  • 22
  • 27
  • Ah, I see. I'm not gonna paste the entire html into the function however, what would be the most efficient way of handling this? Trying to be DRY here. – Sebastian Olsen Feb 15 '16 at 18:06
  • split only the element you need into another html, pass this code to the function, and use include in the templates – Aviah Laor Feb 15 '16 at 19:21
  • what if the html is dynamic (ie model based variables) – Sebastian Olsen Feb 15 '16 at 19:24
  • There are solutions, like render these partial templates, then pass the rendered code. But be careful, otherwise you will go to the rabbit hole of building another framework. It's the same question django faces: block, templates, dynamic templates etc. – Aviah Laor Feb 15 '16 at 19:35
  • I see, I really just want to make my application single-page, so I figured this wouldn't be too hard with django. I am gonna have to lookup how to render partials first and then pass the code, if there's not an easier way, maybe? my goal is that since this website is audio based, there has to be a way for the audio to not stop playing when you navigate. – Sebastian Olsen Feb 15 '16 at 19:46
  • I've been linked to that so many times. It just won't install. I get the same `egg_info error 1` everytime I try. It sucks because that looks like it could really solve my predicament. – Sebastian Olsen Feb 15 '16 at 19:54
  • I know, but look at the code, or other pjax implementations, for the idea. Either the server sends complete HTML snippets, or just data and client side js renders the page – Aviah Laor Feb 15 '16 at 19:56
  • wait, so I can send a TemplateResponse, and ajax could pick it up? – Sebastian Olsen Feb 15 '16 at 20:00
  • Yes, in the jQuery ajax you get success function which receives the data. If the data is HTML, then put it in some element `success:function(data){$("#someElement").html(data);}` – Aviah Laor Feb 15 '16 at 20:05
  • Alright, so how can I tell my views to send the rendered blocks? so for example, if I send it using json, I could have one response_data = {} dictionary and then for block1, I could send response_data[block1] = "block1 html", and response_data[block2] = "block2 html" and then inject the respective code into the page, right? – Sebastian Olsen Feb 15 '16 at 20:07
  • Yes, exactly. Render the template with `django.template.loader.render_to_string()`, and then send the string to the client, and inject it in place – Aviah Laor Feb 15 '16 at 20:14
  • I'm trying to move this discussion to chat, but it's failing. Would you be interested in helping me more over a chat room? I really appreciate all the help, as I am new to this. – Sebastian Olsen Feb 15 '16 at 20:46
  • Ok move this to chat – Aviah Laor Feb 15 '16 at 21:00
  • http://chat.stackoverflow.com/rooms/103532/discussion-between-sebastian-olsen-and-aviah-laor – Sebastian Olsen Feb 15 '16 at 21:03
  • can't login to the chat – Aviah Laor Feb 15 '16 at 21:11
  • That's weird, does it give you any message? – Sebastian Olsen Feb 15 '16 at 21:12
  • just says "login to talk", which I did, twice, on Chrome, Safari and FF – Aviah Laor Feb 15 '16 at 21:17
  • Hmm. Probably a bug in which the devs will get to. Alright, so now I have django.template.loader.render_to_string(), and it works and gives me the whole rendered template but I would like it to only give me the contents of my blocks, since injecting the header and footer when it is already included seems dumb to me. – Sebastian Olsen Feb 15 '16 at 21:19