django, secondary data in subfolders - django

I am working on an informational site. I am attempting to access files in a subdirectory using data from the django db.
Ex: if the record.id = 1 and the file is desc.txt, I want to grab /1/desc.txt
I currently have two items that I'm trying to access this way. The image file will work if I hard code the location, but I haven't been able to get it to work from the record data. The other one, I'm trying to load a description file into a div using jQuery and .html(), and can't get it to work at all.
The relevant section of code:
{% if aRecord %}
{% load static from staticfiles %}
<h1>{{ aRecord.Name }}</h1>
<br/>
Born: {{aRecord.Birth}}<br/>
Died: {{aRecord.Death}}<br/>
<div id="descArea"><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></div>
<script>
descfile = 'Authors/1/desc.txt';
$('#descArea').text(descfile);
$.get("{% static 'Authors/1/desc.txt' %}", function(data) {
$('#descArea').html(data);
});
</script>
<br/>
{% else %}
Requested author not found.
{% endif %}
This is the hard-coded version that works, but I need it to work from the aRecord data. The 1 in both cases should come from the record id, and the image filename in the img tag should as well.

It sounds like this is really a question about how to produce a file path from dynamic data. Is that the case? If so, you will probably need to use string substitution.
In order to produce a string like '/1/desc.txt' where the 1 is given by a record id, you could do something like this:
path = '/{}/desc.txt'.format(record.id).

Related

Reference Wagtail root page in templates

Currently I display a link to my sites homepage in the base template using this code :
{% if page.slug != 'homepage' %}
<!-- insert link code here -->
{% endif %}
However I like to reuse my code and sometimes the page is called something else. What I would like to write is something like :
{% if page != request.site.root_page %}
However this does not work, although if I display the values of these fields in the template they are both equal or not as expected ...
<p>{{ request.site.root_page }} and {{ page }}<p>
Results in :
<p>Contact and Contact</p> # On the root page
or
<p>Contact and Test</p> # On a different page
The opposite problem to this as the data is not specific to one page, but to every page except one.
What am I missing?
Okay in the process of explaining the question, I also found the answer. It doesn't work (I believe) because although these values look the same, they are actually objects with different properties, therefore the comparison fails.
In order for the comparison to succeed you need to extract values from each object and compare them. So this will not work ...
{% if page != request.site.root_page %}
However both of these do work ...
{% if page.title != request.site.root_page.title %}
... or ...
{% if page.url != request.site.root_page.url %}
Kicking myself now, but hopefully my public humiliation will help someone in the future.

How to use Django template tag within another tag?

I have a Django website that I'm trying to get internationalized. The image files are all encoded with the language code of two letters. So when a user switches the language, the references to image files are updated with the language code in templates as follows:
<img src="{% static 'website/images/contact_us_{{ LANGUAGE_CODE }}.png' %}">
Problem is, I have to have a tag as well for the path of static content. What is an elegant way to solve this?
Per #MarAja suggestion, I followed his/her question and solution here which was practically identical to mine. I'm posting what I did, so whoever that lands on this page has a solution. During my research, I did not stumble upon #MarAja's post.
The code is an exact copy, and the choice not to use add tag is because according to the Django documentation, it tries to cast the arguments to an int i.e. not intended for strings.
Full code:
# Custom Template tag file named "custom_app_tags.py"
from django import template
register = template.Library()
#register.filter
def addstr(s1, s2):
return str(s1) + str(s2)
Finally, usage:
{% load staticfiles %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% load custom_app_tags %}
<img src="{% static 'website/images/contact_us_'|addstr:LANGUAGE_CODE|addstr:'.png' %}">
Note, I included everything so that whomever gets here later, gets a complete picture of what is going on.

Django: Variables inside static tag

The question here seems to be very similar to mine; however, I tried what was suggested there but it did not work in my case so perhaps my question is different after all.
In my html file (in the <script></script> for the Javascript section), I have:
var snd = new Audio("{% static 'updateMap/cual_es_su_nombre.mp3' %}");
snd.play();
which plays the mp3 just fine; however, I would like to be able to replace the file name: cual_es_su_nombre.mp3 with a variable. I am getting the file name(s) from the server.
So, the first thing that I do is to load the file names into a Javascript array:
var all_file_names = new Array();
{% for item in all_file_names_from_server %}
all_file_names.push("{{ item |safe }}");
{% endfor %}
Then, ultimately, I would like to be able to do this for example:
var snd = new Audio("{% static 'updateMap/'|add:all_file_names[0] %}");
snd.play();
However, that does not work...
The Django template engine will have completely finished rendering the page before passing it to the browser. You can use it to write Javascript, but you can't access it from Javascript or in ways that depend on Javascript data structures. I think your best bet would be to build an array of the resolved static URLs rather than just an array of the filenames (possibly instead of that array if you don't need both). Something like:
var all_file_names = new Array();
{% for item in all_file_names_from_server %}
all_file_names.push("{{ item |safe }}");
all_file_uris.push("{% static 'updateMap/'|add:item|safe %}");
{% endfor %}
Then:
var snd = new Audio(all_file_uris[0]);
snd.play();

Querying a single field within a Jinja2 template

I'm working on an application where users can enter work requests, and subsequently go in and search for requests. The issue I'm having is building out the request summary screen. Basically, it lists the results of a search query. The snippet from the template is as such:
{% for req in workrequests %}
{{ req.id }} {{ req.customer }} {{ req.dateEntered }} {{ req.Contact }}
{% endfor %}
Here's wher I get hung up. The req.customer, and req.Contact fields are just keys for the customer and contact databases. I want to display the customer name and contact name. I assume the following queries should do the trick:
Customer.query.filter_by(req.customer).one()
Contact.query.filter_by(req.Contact).one()
Problem is, that will return the entire record. I'm just after the name field from both of those tables to put into my template, which is where the problem is. I'm not sure how to proceed with this
Customer.query is a short form of db.session.query(Customer). Use the latter to query for specific columns:
db.session.query(Customer.name).filter_by(id=req.customer).one()
Although I think that what you really want is a single query that gets all the data at once. Something like:
db.session.query(
WorkRequest.id,
WorkRequest.dateEntered,
Customer.name,
Contact.name
).join(
Customer,
Contact
).filter(...)

Django template: Ordering dictionary items for display

I am making a website that displays a user's chosen youtube videos. A user can enter a comment for each video.
I want to display (in this order):
User comment
video title
I have already made the view and have created the following list of dictionary items. Each one represents one video. I send this to my html page:
[
{"my_own_object": vid_obj1, "youtube_obj": obj1}
{"my_own_object": vid_obj2, "youtube_obj": obj2}
]
"youtube_obj" is the object supplied by youtube, which contains the url, title, rating, etc. "my_own_object" contains the user's comments as well as other information.
I iterate over the list and get one dictionary/video. That's fine. Then I need to display the video's information:
{% for key,value in list.items %}
{% if key = "my_own_object" %}
<div>
<p>{{value.user_comment}}</p>
</div>
{% endif %}
{% if key = "youtube_obj" %}
<div>
<p> {{value.media.title.text}}</p>
</div>
{% endif %}
{% endfor %}
This works, except that, because I cannot determine the dictionary order, I might end up with:
Video title
User comment
I thought I could get around this by assigning variables (and then printing the values in the proper order), and am still reeling from the fact that I cannot assign variables!
So, how can I get around this? Can I pluck the key/value that I need instead of iterating over the dictionary items - I tried looking for ways to do this, but no luck. Any other ideas? (I need to pass both video objects as I may need more information than comment and title, later.)
You can use dictionary keys directly:
{% for item in list %} {# PS: don't use list as a variable name #}
<p>{{item.my_own_object.user_comment}}</p>
<p>{{item.youtube_obj.media.title.text}}</p>
{% endfor %}
Just iterate twice. Once for the videos, and once again for the comments. Or, split them into their own dictionaries that are passed through to the template. That's probably a better option, as you avoid iterating twice over the dict. For very small dicts this will be no problem. For larger ones, it can be a problem.