So I want to make a blog post with HTML formatting from the admin page directly. For example from the models.py, you see the description is a TextField. When I go to the admin page to make a blog post, I want to be able to add HTML tags to my blog. So the text field will have HTML content. While I call the blog post onto the HTML template I want it to read the description as a HTML file and not just a text field.
models.py
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
date = models.DateField()
Blog.description at admin page
<HTML>
<body>
<p>Welcome to my first blog post!!</p>
</body>
</html>
blog.html
<h1>{{ blog.title }}</h1>
<hr>
<p>{{ blog.description }}</p>
Any help is appreciated. Thanks!
You can render it with the |safe template filter [Django-doc]. This will disable escaping HTML fragments, and it will thus no longer convert < to < for example:
<h1>{{ blog.title|safe }}</h1>
<hr>
<p>{{ blog.description|safe }}</p>
You however might want to take a look at the django-ckeditor package [GitHub] which offers a dedicated field, widget, etc. to enable editing the text with respect to rendering.
Related
I have two apps: blog and mysite.
In the project folder, I have a template which includes a sidebar template. This sidebar is shown on every page of the project (index pages, mysite pages, blog pages).
One part of this sidebar should show a list of the latest x blog entries (independent of the page where the user is).
blog/models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=264)
text = RichTextField(config_name='detail_text_field', default='')
created_date = models.DateTimeField(default=timezone.now)
blog/views.py
class LatestBlogEntriesListView(ListView):
model = Post
template_name = 'blog/_latest_blog_entries_list.html'
def get_queryset(self):
return Post.objects.all().order_by('created_date')[-3:]
sidebar.html
<div class="row">
{% include 'blog/_latest_blog_entries_list.html' %}
</div>
_latest_blog_entries_list.html
<h4>Latest Blog Entries</h4>
{% for post in objects %}
{{ post.title }}
{% endfor %}
Unfortunately, this does not work. My sidebar only shows the h4 "Latest Blog Entries", but not the posts. How can I do this?
Any help is highly appreciated!
I found to use a context processor, as described in this post: https://dev.to/harveyhalwin/using-context-processor-in-django-to-create-dynamic-footer-45k4
This allows to access a context variable within all pages.
When using ListView the default object is called object_list. Try changing your code to this:
{% for post in object_list %}
{{ post.title }}
{% endfor %}
You can also change this variable name in the view, so that when you catch it on the template, it's a custom name.
class LatestBlogEntriesListView(ListView):
model = Post
template_name = 'blog/_latest_blog_entries_list.html'
context_object_name = "your_new_object_name"
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!
I have taken a hint from this post
Customising tags in Django to filter posts in Post model
I have created the template tag but I am not sure how to use it in my html. I have a home.html where I want to show three featured post. I am looking for something like {% for post in featured_post %} and then show the post detail.
Also, do I necessarily need to create a featured_posts.html as in the above post because I don't want any extra page for the featured post. I just want them to add on my home page in addition to other stuff.
What I am trying to do is I have created a template tag as under
from django import template
register = template.Library()
#register.inclusion_tag('featured_posts.html')
def featured_posts(count=3):
if Post.is_featured:
featured_posts = Post.published.order_by('-publish')[:count]
return {'featured_posts': featured_posts}
The problem I am facing here is I can't import the Post model from model. My directory structure is somewhat like this:-
I have an app named posts.
Inside that I have models.py and templatetags module and inside the template tag I have blog_tags.py
I couldn't do the relative import.
And then created a new page featured_posts.html as under:-
<ul>
{% for post in featured_posts %}
<li>{{ post.title }} </li>
{% endfor %}
</ul>
Now, I want to use it in my home.html. How can I use it?
Edit:- As mentioned above I could load the models as under:-
from posts.models import Post
home.html
{% load blog_tags %}
{% featured_posts %}
Call your tag. That's it.
or
{% featured_posts count=15 %}
Note, featured_posts here is not the post list (which is iterated in for loop) from context but function name: def featured_posts(count=3). They have the same name in your code and probably this has confused you a little.
For example i have very simple news plugin
Part of models.py:
class SimpleNews(CMSPlugin):
image = models.ImageField()
title = models.CharField(max_length=20)
excerpt = models.CharField(max_length=50)
text = models.CharField(max_length=1000)
And two different templates, one for short news and one for full news:
Short:
<h1>{{ instance.title }}</h1>
<p>
{{ instance.excerpt|safe }}
</p>
Full:
<img src={{instance.image}}/>
<h1>{{ instance.title }}</h1>
<p>
{{ instance.text|safe }}
</p>
I need to switch between this templates depending on adress. How can i do that?
So, i find answer by myself.
Vewy useful link here https://stackoverflow.com/a/34804271/6198007.
If switching is slow you'll need to add
cache=False
in your plugin in cms_plugins.py, after that all should be fine.
Sorry for my english.
I am trying to create a blog index page where all the blog post entries are shown. But i want to limit the content of the post body to certain amount (Similar to any blog you see on the internet) so not all the content is visible but when user click on Read More link he can see that particular post in details.
I know how to create page for single article but i am not able to figure out how to limit the post body content. Do i need to change anything in the model or i can do this directly from templates
<h1>{{ post.title }}</h1>
<p>{{ post.post_body }}</p>
Read More
I have declared post body as textfield
post_body = models.TextField()
truncatechars¶
Truncates a string if it is longer than the specified number of characters. Truncated strings will end with a translatable ellipsis sequence (”...”).
Argument: Number of characters to truncate to
For example:
{{ value|truncatechars:9 }}
If value is "Joel is a slug", the output will be "Joel i...".
docs
You can use Built-in Template tag "truncatewords", like this below:
{{ post.post_body | truncatewords:50 }}
This will show the first 50 words of your post.
Here is the Documentation