Django-CKeditor: How to show RichTextFields in templates - python

The problem is that I want to show the content of a Post in the template but I don't know how
The model of Post is:
from ckeditor.fields import RichTextField
class Post(models.Model):
...
content = RichTextField(verbose_name='contenido')
...
And in the template I have a for to show all the post that is like this:
{% for post in posts %}
...
{{ post.content }}
...
{% endfor %}
But when I see the page in the browser shows this:
< p > Post content < /p >
Instead of this:
Post content

You need to mark the content as safe. So change your template to:
{% for post in posts %}
...
{{ post.content|safe }}
...
{% endfor %}
By default HTML is not escaped and so is displayed as text, which is why you're seeing the <p> tags. You need to mark the field as safe so that Django renders it as HTML. See the documentation for more info.

{{article.body|safe}}
or
{{article.body|truncatechars:150|safe}}
or
{{article.body|truncatewords:25|safe}}

Related

Is there a way to add actual HTML to a template from strings containing HTML markup in Django?

So, I want to convert a string I have containing HTML tags converted from a Markdown file into actual HTML. Then inserting the HTML afterwards into a template via Django (this is my first time ever using Django).
What my current output looks like:
Instead of getting plain text, I want the HTML shown in the screenshot to be executed like normal HTML.
Code from my views.py file:
from django.http.response import HttpResponse
from django.shortcuts import render
from markdown2 import Markdown, markdown
import random
from . import util
import html.parser
# index output
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
# function to render wiki entries
def page_render(request, title):
entry = util.get_entry(title)
if entry != None:
markdowner = Markdown()
content = markdowner.convert(entry)
return render(request, "encyclopedia/display.html", {
"title": title,
"content": content
})
else:
return render(request, "encyclopedia/error.html")
Code from my HTML template:
{% extends "encyclopedia/layout.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block body %}
{{ content }}
{% endblock %}
Thanks in advance for the help!
Kind Regards
PrimeBeat
You can use the safe tag.
Insert content like this : {{ content|safe }}
If you don't want the HTML to be escaped, look at the safe filter and the autoescape tag:
safe:
{{ myhtml |safe }}
autoescape:
{% autoescape off %}
{{ myhtml }}
{% endautoescape %}

Text area not reading HTML

I have Django´s Blog APP installed, all working fine, but I need to add posts (via admin) with HTML in the post content field, now, the text area can only read plain text (it doesn´t render HTML).
This is the field:
(models.py)
content = models.TextField()
This is the HTML for this field:
<h6 class="card-text" ><small>{{post.content|slice:":500" |linebreaks |safe}}</small></h6>
Question is: are there special configs for Django/Python in order for the field to render HTML?
The safe tag should already do that... have you tried this:
{% autoescape off %}
{{ post.content }}
{% endautoescape %}
https://code.djangoproject.com/wiki/AutoEscaping
Hope this helps!

Getting a unexpected link in django template

I'm practicing a simple blog site, where if I clicked in author names, it shows the associated post! If I used two different view function the output is fine but if I implemented in one function, in author's post page it shows a url which should not! The screenshot of the html page:
The Url Link contain author post page link! but according to the code it should display the post link!
Url Link
I'm pasting my all code for better understanding. Thanks in advance!
This is my urls.py:
urlpatterns = [
url('^$', views.url_list, name='url_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<post>[-\w]+)/$',
views.post_details, name = 'post_links'),
# url(r'^author/(?P<author_slug>[-\w]+)/$', views.author_posts, name = 'url_list_by_author'),
url(r'^author/(?P<author_slug>[-\w]+)/$', views.post_details, name = 'url_list_by_author'),
]
and my view.py is:
def post_details(request, year=None, month=None, day=None, post=None, author_slug=None):
author_post_list = None
if year:
post = get_object_or_404(UrlPost, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day,
)
if author_slug:
author_post_list = UrlPost.author_manager.author_post(author_slug)
post = None
return render(request, 'detail.html', {'post': post, 'author_post_list': author_post_list})
and html page:
{% extends "base.html" %}
{% block title %}{{post.title}}{% endblock %}
{% block content %}
<h1>{{ post.title|title }}</h1>
<p>{{ post.publish }}</p>
<ul>
{% for author in post.author.all %}
{% if forloop.first %}
<li><h4>Author: </h4></li>
{% endif %}
<li><h4>{{ author|title }}</h4></li>
{% if not forloop.last %}
<li><h4>, </h4></li>
{% endif %}
{% endfor %}
</ul>
<p>{{ post.description }}</p>
Url Link
{% include "author_post.html" %}
{% endblock %}
The first 'url link' you see at the top comes from this line in your html template:
Url Link
All the rest of what is displayed comes from the author_post.html template. The url link is not "additional", actually it's just that everything before is missing.
Probably because the post variable is None. If you actually inspect the generated html, it will look like this:
<h1></h1>
<p></p>
<ul>
</ul>
<p></p>
Url Link
(and the here you will have the contents of author_post)
OK, now for how to solve this: you should not use the same view to display the post and the post author's post. You should create two separate views. Each with its template. Then, assuming you named the new view author_posts in your urls.py:
urlpatterns = [
url('^$', views.url_list, name='url_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<post>[-\w]+)/$',
views.post_details, name = 'post_links'),
url(r'^author/(?P<author_slug>[-\w]+)/$', views.author_posts, name = 'url_list_by_author'),
]

Django: How to associate a comment to its corresponding OP in the HTML template?

I have designed a simplistic posting and comment system where each postcomment object is associated with its corresponding newpost object using foreign key. My problem is that the comments in the template aren’t showing under their corresponding newpost object. For example, if there are a total of 3 newposts and 3 comments under each post for a total of 9 comments, the template displays all 9 comments under each 3 posts (for a total of 27 comments). I need help figuring out how to correctly associate each comment with its corresponding post and not just loop through my ‘allcomments’ field under each post. Thanks for any help and hints.
postset = pagename.newpost_set.all().order_by('-postdate') #i use this to get a queryset of all posts on the selected page and order them so newest posts show up at the top
allposts = newpost.objects.filter(newposttag=‘userpage’) #i use this to get a queryset of all posts on the corresponding user’s page for the next line, this might seem redundant after the above, but it works because the postset is what I end up using in the template.
allcomments = postcomment.objects.filter(commenttag=allposts) #i use this to get a queryset of all the comments from each post in the ‘allposts’ queryset
Here is my template for displaying the above information that I have acquired
{% for postset in postset %}
<br>{{ postset.postcontent }} {{postset.postdate }} - {{ postset.postlikes }} likes Comment</br>
{% for allcomments in allcomments %}
<br> {{ allcomments.comment }} {{allcomments.postcommentdate }} - {{ allcomments.commentlikes}}
{% endfor %}
{% endfor %}
How about updating your template as follows:
{% for post in postset %}
<br>{{ post.postcontent }} {{post.postdate }} - {{ post.postlikes }} likes Comment</br>
{% for comment in post.postcomment_set.all %}
<br> {{ comment.comment }} {{comment.postcommentdate }} - {{ comment.commentlikes}} </br>
{% endfor %}
{% endfor %}
This way, you iterate over your posts and for each post, you retrieve the comments related to that post through the post.postcomment_set.all expression.
Please let me know if that helps you.
ps: I don't think that you need those three queries in your view though.

Django-cms haystack search - placeholder content

i have problem with results in django-cms and haystack search. I'm using django-cms-search plugin, haystack as backend. Haystack returns correct results. But i want to show "teaser" in search results.
I can access absolute URL and title of page via template this way:
{% for result in page.object_list %}
<div class="searchResults">
<h2>{{ result.object.get_title }}</h2>
{{ result.object.placeholders.all }}
<p>{% blocktrans %} Read more {% endblocktrans %}</p>
Problematic part is {{ result.object.placeholders.all }}. I have on every page content in placeholder with name content.
{{ result.object.placeholders.all }} returns only name of the placeholders.
Search results should look like this:
PAGE TITLE
PAGE TEASER
READ MORE LINK
In teaser there should be first 50 words from search-matched page.
Is this possible to access placeholder content from template?
Thank you for your tips.
Haystack has templatetag higlight which creates "teaser" as i requested.
Template code can look like this:
{{ result.object.get_title }}
{% highlight result.text with request.GET.q max_lenght 40 %}
{{ result.object.get_absolute_url }}
Thanks to guys from #haystack IRC channel.

Categories

Resources