Rendering in django template paragraph behaves weird - django

I have the following code in my template:
<p>{{ form.end_at }}</p>
<p>{{ form.weekdays }}</p>
It renders as follows:
<p><input type="text" name="end_at"></p>
<p></p>
<ul>
<li>..</li>
..
</ul>
<p></p>
So why does the first call places the input in the p and the second creates two p tags instead of placing the ul in the p as well?

It's not Django doing this, its the browser "normalizing" what it sees as invalid markup. According to HTML spec, <p> tags can't contain <ul> tags:
List elements (in particular, ol and ul elements) cannot be children
of p elements.
The spec recommends either closing the paragraph before staring the list: <p>...</p><ul>...</ul><p>...</p> (which is exactly what the browser did) or to use <div> instead of <p>.
To test, try downloading the page using wget and opening in a text editor - you'll see that the generated markup is what you told Django to render, no extra tags added.

Related

Javascript returns the same id for every iterated element in html

I have website which i build using Django where every visitor can leave their message or press a like button on any comment. I would like to show how many of a comment has been liked by the user.
As each comment is unique, I think to access the comment_id attribute which I wrote in the html part. I then use a simple js function to retrieve the id. The problem is, although html is showing unique id for each comment, Javascript still return the same id, that is the id of the first comment that is written on the page. Can someone tell me where is my mistake in this case?
Thank you in advance for your help.
my code in js:
function likeButton(){ let el = document.getElementById("chat-icon-thumbsup") alert(el.attributes["comment_id"].value) };
my html code, which is looping the datatable records "comment" from a datatable in Django framework:
{% for comment_ in comments %} <strong> {{ comment_.name }} - {{ comment_.date_added }} <button><i comment_id="{{ comment_.comment_id }}" id="chat-icon-thumbsup" class="fa fa-fw fa-thumbs-up" title="like this comment" onclick="likeButton()"></i></button> {{ comment_.nr_of_likes }} <br/> </strong> {{ comment_.body }} <br/> {% endfor %}
image 1: here you see when I inspect the DOM elements, it retrieves different "comment_id"
enter image description here
image 2 and image 3: every button pressed in the comment line alerting the same id, which is 16
enter image description here
I tried to google any possible same problem, but no solutions found
In HTML an ID should be unique on every page. JS will therefore only return the first field it finds with that ID. What you should be using is a class-name that defines your field, like this for example:
<i id="comment_{{ comment_.comment_id }}" class="fa fa-fw fa-thumbs-up chat-icon-thumbsup" ....>
Then you can use document.getElementsByClassName("chat-icon-thumbsup"), there is a reason why it's called getElementById as singular and not getElementsById

Django 1.10 Print values in same line in Templates

i want in same line print two value look like "1. Question ...".
but first {{ }} after set new line. look like this,
"1."
"Question ..."
{% for q in question %}
<p> {{ forloop.counter }}. {{ q.question|safe }}</p>
{% endfor %}
How can i print two value in same line in template ?
I want this:
1.Question
2.Question
...
Based on your comment, you say that q.question is the content of a CKEditor. Often times, these output at least wrap the content inside a <p> tag. In this case, the result output generated by Django would a nested <p> tag inside the <p> from your template:
<p>1. <p>Question</p></p>
This is invalid HTML, but the browser tries to render it as best as it can. I think you can either include the number inside the CKEditor and exclude it from your template or change your field to store a simple CharField, and keep your HTML unchanged.
This depends on the flexibility you want in your application.

Writing multiple page pdf from html template using weasy print and django

Hi am generating PDF's from html template containing a table which number of rows vary, problem is when the rows are in excess of certain number(12) the rest of the rows plus the footer are pushed further below and don't appear in the generated pdf.How can I make it dynamic so that extra info is pushed to new page each having atleast a certain number of rows, or is there a way weasy print to move data to another page if the current is full
So far I have page breaks on the template but it has worked.
{% for record in data %}
<tr>
<td> {{ record.id}}</td>
<td> {{ record.date}}</td>
</tr>
{% if forloop.counter|divisibleby:12 %}
<div style="page-break-after: always;"></div>
div style="page-break-before: always;"></div>
{% endif %}
{% endfor %}
Removed the body tags from my template and it worked without using page breaks, weasyprint limits everything in the body tag to be one document in a page.
another answer that helped
I've thrown together a repo to try and reproduce your issue here, and was unable to.
There's a small syntax error in your question - you're missing the < off your second <div />, but apart from that, it all looks good.

django display textfields

I have a form with textfields in Django, and users enter texts line by line.
When I look at the entries in admin side, I saw exactly how user wrote it but when I display it on my website, in Django templates, it just joins the sentences and I couldn't display the text line by line anymore.
To illustrate, user enters text as
-bla
-bla1
-bla2
However, it looks like in my page as
-bla1-bla2-bla3
This is my code in the template:
<div>
<p>
{{ rev.myTextField }}
</p>
</div>
In HTML, newlines between text don't imply a newline in display; you need to use HTML to insert the newline. The most straightforward way is with the <br /> tag, although there are other methods as well.
Django has a template filter for this: use |linebreaks. Here's the Documentation.
So, change:
{{ rev.myTextField }}
to:
{{ rev.myTextField|linebreaks }}
Try "safe" tag
{{ rev.myTextField|safe }}
using
{{ rev.myTextField|linebreaks }}
disables <small> tag, its better to use
{{ rev.myTextField|linebreaksbr }}
it just put <br> tag, not <p>

How do I inject actual html from the model to the template?

In my admin, I have a text area where the user can input html:
<ul>
<li>blah</li>
</ul>
<p>
Stuffs
</p>
When I push the above to my template and I view the source of the page, I get:
<ul>
<li>blah</li>
</ul>
<p>
Stuffs
</p>
What should I do with my output so that I see actual html in the page source?
you need the 'safe' filter. As it's autoescaped.
{{ my_html|safe }}
See the template tags documentation here, check the autoescape tag description.
By “text area”, do you mean a <textarea>?
Because if so, escaping < to < (et al) is what you must do inside a textarea or any other HTML element: Django is doing the Right Thing. You see the correct, decoded version of the text on the page; who cares what the source looks like?
If you don't escape the contents of a textarea you are not only generating invalid HTML, you're also opening yourself to attacks where the user inputs:
</textarea>
<script>
steal(document.cookie);
location.href= 'russian malware site';
// etc.
</script>