I have a blog set up with Django that I use to post some of my notes and personal how-tos. I have an articles
model that takes data from a form
rendered in the template
. The application displays my articles posted dynamically in the template. My goal is to include code snippets as a <pre> tag
within the form data that I post, while writing as little HTML as possible.
models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
class Article(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])
views.py
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from .models import Article
class ArticleListView(LoginRequiredMixin, ListView):
model = Article
template_name = 'article_list.html'
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
template_name = 'article_new.html'
fields = ('title', 'body',)
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
templates/article_new.html
{% extends 'base.html' %}
{% block title %}New article{% endblock title %}
{% block content %}
<h1>New article</h1>
<form action='' method='post'>
{% csrf_token %}
{{ form.as_p }}
<button class='btn btn-success ml-2' type='submit'>Save</button>
</form>
{% endblock content %}
templates/article_list.html
{% extends 'base.html' %}
{% block title %}Articles{% endblock title %}
{% block content %}
<br/>
<div class='row'>
<div class='col-8'>
{% for article in object_list %}
<div class='card' style='background: #292b2c'>
<div class='card-header' style='background: #292b2c;'>
<span class='font-weight-bold'>{{ article.title }}</span> ·
<span class='text-muted'>by {{ article.author }} | {{ article.date }}</span>
</div>
<div class='card-body' style='background: #1a1a1a;'>
<p>{{ article.body|linebreaks }}</p>
<a href="{% url 'article_edit' article.pk %}">edit<a> | <a href="{% url 'article_delete' article.pk %}">Delete</a>
</div>
<div class='card-footer' style='background: #292b2c'>
{% for comment in article.comments.all %}
<p class='font-weight-bold'>
<span class='font-weight-bold'>{{ comment.author }} ·</span>
{{ comment }}
</p>
{% endfor %}
</div>
</div>
<br />
{% endfor %}
Is there a way that I can display code snippets as a <pre>
tag within the form I posted for tutorial purposes?
I tried wrapping the {{ articles.body }}
in <pre>
tags within the actual template but that will just turn all text into <pre>
. I have successfully kept the whitespace from my original entry by using {{ articles.body|linebreaks }}
I don't necessarily want to use RichTextField() because I want to keep it simple but I will if I have to.
CodePudding user response:
If you want to keep it simple and short, you could add the safe
templatetag to your body. This will allow you to render HTML from your input:
https://docs.djangoproject.com/en/4.1/ref/templates/builtins/#safe
...
<div class='card-body' style='background: #1a1a1a;'>
<p>{{ article.body|safe|linebreaks }}</p>
...
</div>
...
And then, when you're writing the blog, you can wrap the code inside a <pre>
tag:
Hello this is my tutorial
This is a piece of code:
<pre>my_function()</pre>
Hope you enjoyed it!
And that will be rendered.