How do I avoid Django's `|linebreaksbr` and Bootstrap style conflict? - python

I'm trying to store newline character inside model's CharField but it's not rendering correctly. <br/> and <br> both display as plain text, while |linebreaksbr is destroing bootstrap's styles in that text.
3 of my attempts to make it work:
<p>{{ greetings.title_2 }}</p>
<p><pre>{{ greetings.title_2 }}</pre></p>
<p>{{ greetings.title_2 | linebreaksbr }}</p>
And the result looks like this:
I want both bootstrap's style (like in first line) and new line stored inside variable. There is a way to do that by deviding one model field in two and adding <br/> tag into html file, but I wonder if there is better and simpler way for that. Any ideas?

Related

Django - How to make anchors change HTML list

I have the following snippet of HTML:
On my django webpage, i get a list that looks as follows:
Each "Part" anchor corresponds with a Part object in Python. Now, I'd like to make it so that when the user clicks on "Part_2", the datapoints of that Part are shown just below it.
On the image, the datapoints of the first part are shown within the nested list. I hard coded this. I looked into calling a python function with an argument from the template, but that is not possible.
What would be an easy way to make this happen?
You can achieve this on the client side. First, create a detail element in your HTML and put a summary and the tags that you need (in this case, I'll be using a <p></p>) as childs:
<details>
<summary>Part 1</summary>
<p>Epcot is a theme park at Walt Disney World Resort featuring exciting attractions, international pavilions, award-winning fireworks and seasonal special events.</p>
</details>
What's inside the summary tag will represents the title and below that goes the hidden text that can be accessed by clicking in the arrow on the side of the title.
Then, make sure you filter in your function in views.py the parts by part_1 and part_2 and then pass them into your context. Lastly, render the items like this:
<details>
<summary>Part 1</summary>
{% for part in part_1 %}
<p> {{ part.tag }}</p>
{% endfor %}
</details>

Django: Change HTML template's font in the middle of a text string that is generated by a {{variable}}

I have a character string generated in views.py like this:
context_dict['advice'] = "Please consider selecting " + var1 +
" as your next choice."
This is displayed in a page whose template has invoked it like this:
{% if advice %}
My advice:
<p style="font-size:20px; color:blue">
<b>{{advice}}</b>
</p>
Thus, the entire sentence comes out with the same font: 20px, blue, and bold. However, I would like the word contained in var1 to be green instead of blue (with the rest of the sentence still blue), so that it stands out.
I don't see a way to do this. I considered moving more of the static text to the template, so that I could just make var1 the variable and apply a different font to it. This kind of approach won't work for now though, because the text that appears static in this example could actually change to 100+ different things depending on what happens in the control flow logic of views.py.
Why don't you try like this:
context_dict['advice'] = "Please consider selecting <span style='{0}'>{1}</span> as your next choice.".format('color:green;', var1)
This requires you to change the variable in the HTML template to:
{{advice | safe}}
I would solve this by separating the strings into three variables. The beginning string, the variable, and the end of the string. This will still allow all three to change with the flow of the program.
views
context['str1'] = 'Please consider selecting '
context['var1'] = var1
context['str2'] = ' as your next choice.'
template
<div class="class1">{{ str1 }}</div>
<div class="class2">{{ var1 }}</div>
<div class="class1">{{ str2 }}</div>
Can you possibly set the dict key to a list? If so, try:
context_dict['advice'] = ["Please consider selecting ", var1, " as your next choice."]
Then in your HTML:
<b>{{advice[0]}}</b><span style="color: green;">{{advice[1]}}</span><b>{{advice[2]}}</b>

rendering of textfield and charfield chomps out extra whitespace (Django/Python)

I've noticed that my template is rendering my model.CharField and model.TextField without any excess whitespace.
For example, if I enter data such as...
This is a test
to see what happens.
The rendered object field will appear as...
This is a test to see what happens.
Is this an intentional feature of Django or have I missed some filter or parameter somewhere?
I've checked the field itself with some debug code (print object.field) and it does contains the extra whitespace, so the problem is in the rendering side.
How can I allow the user to enter paragraphs of data in TextFields? How can I preserve the whitespace that the user may have entered?
As you can see even in StackOverflow your spaces do not display, this is from the source of your question:
This is a test
to see what happens.
Will save in the database as:
This is a test\n\n\nto see what happens.
You have to problems when rendering as html:
Extra spaces between words are stripped on display by the browser, unless it is between <pre></pre> tags
Linebreaks will be rendered as plain text linebreaks, which do not display in the browser unless between <pre></pre> tags.
For spaces, you can use such a template filter to replace them with their html entity equivalent: .
To convert database linebreaks in HTML linebreaks, use linebreaksbr built-in filters. For example, if {{ foo }} is: test\nbar, then {{ foo|linebreaksbr }} will render: test<br />bar
Create a "templatetags" folder in some of your apps with an __init__.py file in it.
Save the snippet for example in someapp/templatetags/replace_tag.py
Load the template filter in the template as such {% load replace_tag %}
Combine replace and linebreaksbr as such: {{ foo|linebreaksbr|replace:" "," " }}
You can also make your own template filter that will process the text into the HTML you need. In any case, refer to the custom template filter documentation for complete information.

Markdown in Django XSS safe

I am using Markdown in an app to display a user biography. I want the user to be able to slightly format the biography, so I'm letting them use the TinyMCE editor.
Then, displaying it in the Django Template like this
{% load markup %}
<div id="biography">
{{ biography|markdown }}
</div>
The problem is, if there is a tag in the biography, it is not being escaped as django does everywhere else. This is the source output from a biography test:
<p><strong>asdfsdafsadf</strong></p>
<p><strong>sd<em>fdfdsfsd</em></strong><em>sdfsdfsdfdsf</em>sdfsdfsdf</p>
<p><strong>sdafasdfasdf</strong></p>
<script>document.location='http://test.com'</script>
How do I set Markdown to escape these malicious scripts?
According to django.contrib.markup.templatetags.markup.markdown's docstrings:
To enable safe mode, which strips raw HTML and only returns HTML
generated by actual Markdown syntax, pass "safe" as the first
extension in the list.
This should work:
{{ biography|markdown:"safe" }}
Markdown in safe mode would remove all html tags, which means your users cannot input HTML segments in the biography. In some cases, this is not preferable. I would recommend you use force_escape before markdown, so anything fed into markdown is safe.
For example, if your biography is <html>I'm really a HTML fan!</html>, using
{{ biography|markdown:"safe"}}
would produce HTML REMOVED.. Instead, if you use
{{ biography|force_escape|markdown }}
The output would be something like
<p><html>I'm really a HTML fan!</html&gt</p>

Django and wrap lines problem

I've a problem from many years.
The problem is a long text not separated by white spaces in a div. No wrap is applied and it breaks all layout.
How can I fix in django in a good way?
This is what I see:
As I understand the question it is HTML-side problem, not django-side. For HTML solution look How to word wrap text in HTML?. If you still want to wrap text in python code, textwrap.wrap will help you.
Also there is convenient template tag for this: wordwrap. It uses django.utils.text.wrap function which seems more suitable for using in Django projects.
This was bugging me as the built-in word-wrap template tag should have just worked. Instead use this...
{{ value|wordwrap:50|linebreaksbr }}
or
{{ value|wordwrap:50|linebreaks }}
depending if you want <br> or <br> and <p> tags
I don't know if it helps, but an approach could be creating a new filter based on truncatewords filter.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#truncatewords
Code looks very simple:
def truncate_filter(value, maxlen):
if len(value) <= maxlen:
return value
return value[:maxlen-2] + '..'
Another ideia is using: {{ username|stringformat:".10s" }} to truncate in 10 characters.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#stringformat

Categories