I'm not sure if the title is technically correct (sorry, I'm new to python+django)
I have a template page that displays whether an application is running or stopped depends on its status. For example:
If app is running I want to display:
<div class="lt">
<a class="play" title="App running">
<span class="text_play">Running</span>
</a>
</div>
<div class="rt">
<input type="submit" onclick="stop_app()" value="stop" class="stop">
</div>
If the application is not running then show this instead:
<div class="lt">
<input type="submit" onclick="star_app()" value="start" class="play">
</div>
<div class="rt">
<a class="stop" title="Application is not running">
<span class="test_stop">Not Running</span>
</a>
</div>
This is kind of stripped down simplified html but my point is how can I avoid repeating myself?
The template is passed a dictionary of applications that it iterates over to display all the applications and their status (running/stopped). So currently I'm iterating over the dict twice, one for "stopped" apps and one for the "running" apps.
Hope it's clear
Thanks in advance
EDIT: This is what I have tried so far:
{% if application.service.status|lower == "enabled" %}
<div>...display running HTML...</div>
{% else %}
<div>...display the non-runing HTML..</div>
{% endif %}
I just want to know if I'm doing the right thing (DRY?)
What you proposed is pretty DRY.
{% if application.service.status|lower == "enabled" %}
<div>...display running HTML...</div>
{% else %}
<div>...display the non-runing HTML..</div>
{% endif %
Keep in mind you'll rely on the return render(request... for determining the html Django needs construct.
Your proposed solution will choose one or the other. I.e. if your non-running HTML needs to switch to running HTML you won't have access to it without another render.
To be more clear and concise, django templates will construct the appropriate HTML leaving out the alternative options or "conditions".
If you learn a bit of jQuery for example you can have elements of the page switch the currently displayed html. Expanding this to ajax will allow you to get status updates from the server and vice versa.
Related
I have a django page which is making an API call then displaying the results through a template. This has been working well but I must have changed something and now half the variables are not displaying correctly. Usually when there is an error calling a variable the template would just display a blank field. However, in my situation the webpage is displaying the code which is calling the variable. Here is what I have:
My HTML Code Looks like this:
<h6>Page</h6>
<ul class="list-inline mx-auto row">
<li class="list-group-item col-md-12">ASN: {{ context.upload.urlscan.page.asn }}</li>
</ul>
<ul class="list-inline mx-auto row">
<li class="list-group-item col-md-12">ASN Name: {{ context.upload.urlscan.page.asnname }}</li>
</ul>
<ul class="list-inline mx-auto row">
<li class="list-group-item col-md-12">IP: {{ context.upload.urlscan.page.ip }}</li>
</ul>
From this code ONLY the first and third line are displaying correctly - These lines are displaying the variables that they are assigned to.
The middle value Labeled 'ASN Name' is displaying the code back. On the webpage it looks like this:
{{ context.upload.urlscan.page.asnname }}
I have verified that the data is coming in correctly and this is happening in several places in my code. Not sure why some variables are working and some are not.
I am using Django 2.1 and Python 3.6 on RHEL 7.x
EDIT
Per the request here is my context creation and render portion
context['type'] = 'url'
context['upload']['cs_response'] = cs_response
context['upload']['cs_domain'] = cs_resp_dom
context['upload']['ppdom_rep'] = ppdom_rep
context['upload']['ppdom_ids'] = ppdom_ids
context['upload']['cs_test'] = ioc
context['upload']['urlscan'] = scan_res
context['js'] = json.dumps(context, indent=4)
return render(request, 'iocs/upload.html', {'context': context})
So this was a pain but I finally figured it out. I wanted to style a div and I did it in a kinda lazy way. My django template was extended from a 'base' template so right under the {% block content %} tag I added a <style> tag.
This worked and styled the div correctly, however for some reason it broke half my variables on the page. I HAVE NO IDEA WHY! When debugging I commented this entire <style> block out and my code was still broken. I had to completely delete the <style> block for it to work again.
Once the <style> block was removed all variables began working...
Python 3.6.3, Django 2.0.3
I'm new to django, but I'm trying to make a pretty simple site where someone can trigger a few tasks that were previously just misc, stand-alone python scripts. Unfortunately those tasks can take a pretty long time. I want to be able to display the output from those tasks in the middle of the following template (where {{ stream }} is) so the user has some meaningful feedback.
{% load pagePieces %}
{% page_header %}
<div class="container">
<div class="row">
<a class="btn" href="/"><i class="fa fa-chevron-left"></i> Home</a>
</div>
<div class="row row-header"><h1>{{ operation }}</h1></div>
<div class="row row-content">
{{ stream }}
</div>
</div>
{% page_footer %}
In my view file I've tried a few different things, but here's about where I'm at now (this is somewhat simplified. I took out some error handling and changed some names):
def myaction(request):
output_template = loader.get_template('myapp/process_output.html')
return StreamingHttpResponse(
output_template.render({
'operation': 'That long running task',
"stream": streaming_wrapper()
})
)
def streaming_wrapper():
output_template = loader.get_template('myapp/process_output.html')
x = yield from a_module.long_running_task()
yield output_template.render({
'operation': 'That long running task',
"stream": x
})
This does stream the output from long_running_task(), but doesn't load the rest of the template until after it's done. At other points, I've gotten the output to stream after the template, but never in the middle, which looks bad because my template has a header and a footer.
I'm not sure how to make this work, and I'm not sure if the answer is in my views or perhaps doing something more complicated with my template.
(I'm also aware this is similar to these 2 questions, but neither of them have satisfactory answers and are years old.
Django: return a StreamingHttpResponse on an existing html page
Django StreamingHttpResponse into a Template)
Try to implement the steps as per this blog of Miguel Grinberg - https://blog.miguelgrinberg.com/post/video-streaming-with-flask/page/8 (This is for for Flask). But you have to follow the same steps and also need to modify the template as per the need. These steps worked for me.
I am building a little web application in Python 3.5, using Flask 0.11.1 and Flask-Admin 1.4.2.
Instead of using Flask-Admin as an administrative interface (only used by administrators of the website), I want it to be used by all the users of the website (to take profit of its awesome CRUD generation with forms using Select2 JS lib, inline forms, list views with filtering, etc.).
With that in mind, I want to override the list view template to be more user-friendly. For that, I am doing the following.
First, in my view I override list_template:
from flask_admin.contrib.sqla import ModelView
class FriendView(ModelView):
list_template = 'friend/list.html'
...
Then, I write the friend/list.html file by extending admin/model/list.html and overriding the block model_list_table defined in it:
{% extends 'admin/model/list.html' %}
{% block model_list_table %}
{% for row in data %}
<div class="col-xs-6 col-sm-4 col-md-3">
{% include 'friend/panel.html' %}
</div>
{% endfor %}
{% endblock %}
The panel.html file represents a Bootstrap panel illustrating each Friend:
<div class="panel panel-success">
<div class="panel-heading">
This friend is named {{ row.name }}.
</div>
<div class="panel-body">
{% block list_row_actions_column scoped %}
{{ super() }}
{% endblock %}
</div>
<div class="panel-footer">
...
</div>
</div>
Here is the problem: as you can see, I use in panel.html the block list_row_actions_column, which is a Jinja block defined in admin/model/list.html.
Of course, this raises the following error:
jinja2.exceptions.UndefinedError: there is no parent block called 'list_row_actions_column'.
because the file panel.html is not extending admin/model/list.html.
I have tried to define panel as a Jinja macro and to import it in friend/list.html, this raises the same error...
I know that I could simply not separate the panel in another file, however my friend/list.html is pretty big, and I think it is a good thing to do it that way, for sake of readibility and decoupling.
Does someone have an idea about how I can proceed?
Thanks,
Edouard
just make an html file and write single block of code in html file then include that file into that particular location where you want to need that code. that is the best method without use of any #block or #micro and for every block of code use a new html file and use this file as a function by including it on that place.
I'm using ng-include like this
HTML
<div ng-app="myapp" ng-controller="myctrl" ng-include="/static/html/main.html"></div>
main.html
{% extends "app\base.html" %}
{% block content %}
<div ng-controller="myctrl1">
some content
</div>
{% endblock %}
base.html
<div ng-controller="myapp2">some content </div>
but this is not working, it is showing an errorr "SyntaxError: Unexpected token % at Object.parse (native)"
Please suggest me a better way to implement this.
I don't quite know what you're trying to do here. Angular templates and Django ones are quite different, even if they superficially share the same {{ var }} syntax. You can't inherit an Angular template from a Django one, or vice versa.
But there's no reason to want to do that anyway. Angular is already loading the template as a partial, which means it will be inserted into the div in base.html. There's no need for inheritance here at all.
I'm quite new at python/django.
I love django's templates, but there is one recurrent thing I cannot find
It's very common for me to have one conditional attribute on a (probably long) HTML tag. Most of the times that's an extra CSS class.
For example, let's say you have two links to switch languages, and you want to enable only one at a time. I find myself doing something like this:
{% get_language_info for LANGUAGE_CODE as l %}
<a href="/path/to/switch/to/spanish"
class="{% ifequal l.code "es" %} disable {% endifequal %}">
<img src="/spanish/flag/url" alt="Spanish">
</a>
<a href="/path/to/switch/to/english"
class="{% ifequal l.code "en" %} disable {% endifequal %}">
<img src="/english/flag/url" alt="English">
</a>
Other examples may be while rendering a list of items and checking for the "selected" one, etc.
On other languages I did this with a ternary operator, but I know that's considered "evil" on the python/django world :-)
I wonder if there's a way to leverage from the "yesno" filter. I've tried to do something like:
{{l.code=="es"|yesno:"disabled,"}}
But I couldn't get it to work... am I missing something?
Thanks in advance.
The problem is simply with your syntax in the code you posted:
{{l.code=="es"|yesno:"disabled,"}}
It's actually processed like:
{{ l.code=={{"es"|yesno:"disabled,"}} }}
(Note: that code doesn't work, it's just meant to illustrate how Django reads it)
What you want is a custom template tag that works like the if templatetag but returns like the yesno filter. You could search around on something like djangosnippets.com; maybe someone has already done the work for you. Otherwise, I'd suggest looking at the Django source code for those two and try to merge them into your own templatetag.
Or you could use jQuery/javascript to set the class:
http://api.jquery.com/attr/
something like this - not tested!
{% get_language_info for LANGUAGE_CODE as l %}
<script>
{% if l.code='es' %}
$('.english').attr('class','disable');
{% else %}
$('.english').attr('class','disable');
{% endif %}
</script>
<a href="/path/to/switch/to/spanish"
id="spanish" class='enable">
<img src="/spanish/flag/url" alt="Spanish" >
</a>
<a href="/path/to/switch/to/english"
id="english" class='enable">
<img src="/english/flag/url" alt="English">
</a>