Page switching using AJAX in Django - python

I am trying to create site navigation using AJAX. I have navigation menu with links to different views (using {% url name %} in template). The thing I am trying to do is to load the page content using AJAX. The page content I am trying to load is enclosed in content block ({% block content %}).
I also found this snippet http://djangosnippets.org/snippets/942/, but I want to use the views I have already defined and only get the content using ajax.
Any suggestions?

You should use django-pjax which is built exactly for that kind of thing.
All you will have to do is to, in the base template, include the whole page or just the block content based on whether the request is ajax or not.
django-pjax does the AJAX calls using the jQuery and manipulates history using HTML5 push state API, which is a very good way to do it and also gracefully degrades in IE older versions.

Template tags like {% block content %} are long gone by the time AJAX sees things. What you want to do is create a named <div> in your content block, like:
{% block content %}
<div id="content"></div>
{% endblock content %}
Then you can use something like this (jQuery) code to load the <div> when needed:
$("#content").load(url, data, loadComplete);
where url is the URL you want to load (HTML expected in return), data is the form data (if any; can be omitted), and loadComplete is the optional function to be called when the data is loaded, and is of the form function loadComplete(responseText, textStatus, XMLHttpRequest) {...}. Even if you don't want to use jQuery, you can get the non-minified jQuery source and see how they do it.

Related

How to load image from backend (SQL textfield ) directly by using Django?

I am trying to make a blogging website. I know django provides argument templates like
{% include images.html with value=sense %}
The above code directly works in HTML and hence everything works. The images are stored in a backend database and connected to everystory by some logic. The user can use the names of the images and call whenever they need to use it
When I try the above code directly in the backend it doesn't work because I think once something is rendered then it doesn't rerender by django HTML
I wish to paste some form of links in the django story backend. such that when it renders in HTML automatically the page should show pics in the appropriate place. If anyone has any idea how to do this kindly let me know.
So when loading stories in the database the user can put some form of links for images in the database and while rendering all images come in a certain format as specified in the block in the blog.So there can be any number of images and the count is not longer fixed as shown in the pics below where I am trying to render a image called sense from the backend which doesn't work.. whereas it directly works in the frontend.
<p>{{object.story_title}}</p>
<p>{{MEDIA_ROOT}}</p>
<p>{{object.story}}</p>
{% include "blogdescription/image.html" with value=sense %}
Thank you for your time.
with regards
Let me start saying that doing exactly what you want is not possible because Jinja will compile and render {{object.story}} and not its content (the include). It does not seem possible to use nested Jinja syntax to load any resources, includes, extends, urls, etc.
Which explains why when you place the include in the template it works but does not inside your model field.
What seems possible is to load an HTML image with a explicit URL to the resource, lets say, the content inside your text field is:
<div style="display: flex; justify-content: center; align-items: center;">
<img src="/static/myimage.jpg" alt="Object Image">
</div>
Template.html (source):
{% block content %}
{{obj.title}}
<br>
{{obj.body|safe}}
{% endblock %}
Alternatively, it is possible to generate a HTML file to render dynamically based on Object.field. Note that this solution is a heavy load on the server, for every request will generate a dynamic file to be rendered.
Obj field value:
{% extends 'base.html' %}
{% block content %}
{{obj.title}}
<hr>
{% include 'includes/image.html' %}
{% endblock %}
views.py:
def story(request, id):
obj = Story.objects.get(id=id)
f = open(f'templates/generated/dynamic_template.html', 'w+')
f.write(obj.body)
f.seek(0)
return render(request, 'generated/dynamic_file.html', {'obj': obj})

Perform action from a form or link without refreshing the page/view with django

I'm developing a project where I need to add members to a group, for that, I go through all registered members and present them in my html template. Each member has the "add" button next to it, but always when doing this it refreshes a page... I would like to know how to do this without needing to refresh, ie click on add and it is already added automatically.
views.py
def add_members(request, id):
plan=Plan.objects.get(id=id)
users = User.objects.all() # extended django's default user model
return render(request,'site/add_members.html', {'plan':plan, 'users':users})
add_members.html
{% extends 'base.html' %}
{% block title %} Add Members {%endblock%}
{% block content %}
<div class="row">
{% for i in users %}
<h4>{{i.first_name}}</h4>
<form method="POST">
{% csrf_token %}
<input type="submit">Add</input>
</form>
{%endfor%}
</div>
{%endblock%}
You cannot do this using only django, since django is by nature synchronous ( in layman's language it means that whenever you want to send/fetch data from the server your webpage will reload). So, you need to use asynchronous technologies like AJAX.
One way to accomplish what you are trying to do is by building a restful API service only for registration ( using django rest framework). Then you can use Ajax to make asynchronous calls to your rest API.
You can checkout this really nice tutorial video by Dennis Ivy for more details on implementation https://youtu.be/hISSGMafzvU.
PS: Ideally people use a frontend framework like React to make all API calls and they make a separate backend using drf, but since you will need it for just one purpose it is redundant and ajax would do just fine.

Extract Mustache variable for use in Django template tag

I am implementing Algolia's search API for Django, and I have a certain Mustache variable {{ObjectID}} that corresponds to IDs for search results. I can only use via {% verbatim %} {{ObjectID}} {% endverbatim %} without having Django's template syntax conflicting.
However, I also need this variable to construct a url for the ID, but the issue is that I can't easily pass the Mustache variable into a form usable directly with Django's templates. As an example, simply doing
{% url "appName:method" {{ObjectID}} %}
conflicts with Django's template syntax, but trying to ivnoke verbatim via
{% url "appName:method" {%verbatim %} {{ObjectID}} {% endverbatim %} %}
does not work either, since calling a template tag in a template tag is disallowed.
I am also unable to store {{ObjectID}} as a temporary variable with a method or offshore url to a separate method, e.g.
function generate (objectID){
return "{% url 'appName:method' objectID %}"
}
//usage of method
link
since Django will process the url on sight and throw NoReverseMatch since objectID is not defined by Algolia yet. Is there a way to extract {{ObjectID}} such that it can be piped back into Django's url constructor?
NOTE: My implementation of Algolia doesn't directly interact with Django's databases, but rather its own indexing of the database that it stores separately. More information on algoliasearch-django's Github
I would suggest you use something like this in the view and pass the value to the template:
reverse('appName:method', args=[1337]).replace('1337', '{{ObjectID}}')
If you must do it only in the template and you can be sure that the {{ObjectID}} part will always be at the end of the URL, you can do it like this:
{% url "appName:method" 1337 as my_url %}
...
Note that the above template code assumes a trailing slash.

How to build the requests handlers when the JInja template has multiple blocks?

I'd like to make a simple website running on the GAE framework/service. It's very small, and i don't really need the whole powerful Django framework, and thus i'm opting for the google-made Webapp2 framework, coupled with the Jinja2 templating langage.
I'm coming from a really bare-PHP-and-HTML-oriented background, so I have a hard time adjusting to the way a real framework works. My current greatest interrogation comes from how the templating system and the request handlers are working together, especially if the the page's template has several "dynamic" elements.
I'll first explain what I used to do in PHP, so you may better understand what i want to achieve.
Let's say I want a website with :
a page title depending on the page being visited, eg : "Mysite.com | Control Panel"
a dynamic menu bar, that may change depending on the user's profile or logged-in status
obviously, a page body that completely depends on the page being viewed
The way i'd do it in PHP is thus here compressed into a simple example, index.php:
<?php
/*here use the $_GET or $_POST variable, and the $_SESSION variable
to figure out who's connected, which page is being displayed,
and store those values in global variables, for the
included modules to use */
include('page_header.php'); // renders the whole <head> </head> tag and its content
echo "<body>";
include('views/menu.php'); //generates the menu, displays it
switch($page_name){
case "home":
include('home.php'); //renders the page body for the homepage
break;
case "articles":
include('home.php'); //renders the page body for the blog articles listing
break;
case "guestbook":
include('home.php'); //renders the page body for the guestbook
break;
}
echo "</body>";
Each included module, using variables from the script that called them (index.php), and the $_POST, $_GET, $_SESSIOn superglobals, figures out what to display, and renders it to HMTL. here index.php also does some kind of very basic routing, using the switch statement.
Now,back to webapp2 and jinja2 framework:
I understand that, to have a modular approach to build a web page with Jinja, you need to use block structures, and extend those blocks. Thus, to build a similar page to the previous PHP example, i made the following template base.html:
<html>
<head>
<link rel="stylesheet" href="/static/css/reset.css">
{% block title %}
{% endblock title %}
</head>
<body>
<div class="menu">
{% block menu %}
{% endblock menu %}
</div>
<div class="body">
{% block content %}
{% endblock content %}
</div>
</body>
</html>
What i don't understand, is how you you'll build the different Handlers that, in turn, generate the context that Jinja will use to render the blocks, and avoiding redundency.
**Also, can I use several different template files that, alone, extend only one block (eg: menu.html, header.html, body_home.html, body_articles.html, ...) **
You can use as a base to answer, this example, from a small example that almost taught me all i needed to know.
Thanks for any help provided, sorry for any grammatical errors, english's not my native tongue.
There's a feature in jinja2 called macros which is pretty much a parameterized include.
So if the includes should be parametized, you would do:
{% macro menu(params) -%}
do something
{%- endmacro %}
And call the macro in your template:
<div> menu('bar') </dib>
If it is not necesary to provide parameters just leave it as static html in the parent template.
For the handler you can follow App Engine hello world example, just use your link to guide you to load jinja's enviroment.
I know you want to translate the php example, but try to do as much logic as posible in your handler instead of the template.
To your second question, yes you can extend just one block if you want, and if you need the parents content there's a {{super()}} block to get them.

Django template variable has wrong value / Javascript in HEAD not executed

I have a Django template base.html:
// inside the javascript
var this_page = "{{ this_page }}";
// inside the HTML part
{% ifnotequal this_page "home" %}
...Some HTML...
{% endifnotequal %}
The part inside the javascript area is incorrect. Actually, Firebug shows me in the HTML tab:
var this_page = "home";
but if I look into the GET inside the Console tab, Firebug shows:
var this_page = "about";
which would be correct, but debugging shows that 'this_page' is set to 'home'.
I also tried it:
{% ifnotequal this_page "home" %}
do some javascript
{% endifnotequal %}
but that did also not work correctly.
What am I doing wrong?
EDIT: This problem only occurs when I access this page via a link. If I access the "about" page directly, I do not have this problem.
Testing on Ubuntu, Firefox 6.0.2, on 'runserver'
JavaScript is a client-side language. The HTML of your template is rendered by the python on server side so you cannot change rendered variable's value through java script code. In your case this_page is rendered html variable and var this_page = "{{ this_page }}"; defines a separate javascript variable and does not change the rendered html this_page variable. So firebug is correct.
You can use Ajax for this purpose if you want to dynamically change the rendered HTML.
The solution to the problem had (perhaps not surprisingly) nothing to do with the question. Apologies that I asked into the wrong direction.
Since I use jquery mobile, it behaved not as I expected: the body content (per default) is loaded per ajax on page change, while the head part is only loaded once.
The solution to the problem I have found here.

Categories