Django not serving text content (First attempt) - python

Summary:
The purpose of this particular Django web app is to just show some lorem ipsum text on the home page, like a blog post. Django is not serving my blog post content. I know the problem is either with my views.py or urls.py (or both).
Details:
I’ve got the data declared inside my models.py. I’ve got my views.py to instantiate the model. I migrated sqlite and successfully logged into the Admin Dashboard and entered some placeholder data.
I’m trying to get Django to serve the placeholder content that I entered into the Admin Dashboard, but instead it’s blank.
Here is my what my test case looks like: https://i.imgur.com/IuOl3G4.jpg
To describe it, you can see The Blog Post, Date, Image, and Body Text HTML heading elements parsed, but none of the content is showing.
Here is my app’s urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.mortems, name='home'),
]
I’ve tried swapping out the quotation marks for the first path() parameter with alls/landings. I’ve tried swapping the name parameter from home to mortems. I also tried using mortem (without the s). None of these changes help.
I've also tried Googling (with variations):
'body text django not showing template'
'django not showing text contents'
Which turned up (among other) SO questions and answers which kind of sound related but are completely different from my issue:
Django Message framework is not showing message in template
Why django template is not showing any output?
Here is my app’s views.py:
from django.shortcuts import redirect, render, get_object_or_404
from mortems.models import Mortem
def mortems(request):
mortem = Mortem.objects.order_by('-pub_date')
context = {'mortem':mortem}
return render(request, 'alls/landings.html', context)
For what it is worth, here are the relevant lines in my model:
class Mortem(models.Model):
title = models.CharField(max_length=161)
pub_date = models.DateTimeField()
image = models.ImageField(upload_to='media/')
body = models.TextField()
now = datetime.datetime.now()
Also, here is my template with the relevant problematic lines (42-50):
<h1> BLOG POST:</h1>
<h4>Date: {{ mortem.pub_date_preference }}</h4>
<br />
Image: <img src="{{ mortem.image.url }}" class="img-responsive center-block" style="max-height:300px;" />
<br />
<!-- Body text should go here : -->
Body Text:
<p>{{ mortem.body|safe }}</p>
The full source code is up on GitHub. Here is the 'mortems' app source code specifically.
For generous SO users with time on their hands, I guess I’m accepting pull requests. haha

I think you need to update the views.py as:
from django.shortcuts import redirect, render, get_object_or_404
from mortems.models import Mortem
def mortems(request):
mortems = Mortem.objects.all().order_by('-pub_date') # returns an iterable queryset
context = {'mortems':mortems} # using plural as it's a list like object
return render(request, 'alls/landings.html', context)
In the template code, you need to iterate over the list to display a single object one at a time. i.e
<h1> BLOG POSTs:</h1>
{% for moertm in mortems}
<h4>Date: {{ mortem.pub_date_preference }}</h4>
<br />
Image: <img src="{{ mortem.image.url }}" class="img-responsive center-block" style="max-height:300px;" />
<br />
<!-- Body text should go here : -->
Body Text:
<p>{{ mortem.body|safe }}</p>
{% endfor %}

Related

The usage of {% url ...%} vs {{ ... }} in Django templates

I've been practicing Djnago and for that, I was building a blog. While in the process of building it, I was faced with an error, while using the following code:
<a href="{% url 'blog_post' post.slug %}">
{{ post.title }}
</a>
While studying and doing other courses something like this would work fine. But now, it will raise this exception: NoReverseMatch.
If I use this code though, it will work just fine:
<a href="{{ post.slug }}">
{{ post.title }}
</a>
While working in different projects the first way would work fine, but this time, it doesn't.
My question is why?
Here is the code in my urls and on my views. Maybe the mistake is here, not somewhere else.
If anyone can explain why this is happening, or where I'm going wrong, it will be greatly appreciated
urls:
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.blog_index, name='blog_index'),
path('<slug:post_slug>/', views.blog_post, name='blog_post'),
]
views:
from django.shortcuts import render
from .models import Post
# Create your views here.
def blog_index(request):
posts = Post.objects.order_by('-
created').filter(published=True)
data = {
'posts': posts
}
return render(request, 'blog/post_list.html', data)
def blog_post(request, post_slug):
post = Post.objects.get(slug=post_slug)
data = {
'post': post
}
return render(request, 'blog/post_detail.html', data)
try this.your problem is that you have a namespace in your urls.py then in your href you should add that namespace('blog').
<a href="{% url 'blog:blog_post' post.slug %}">
{{ post.title }}
</a>
this
<a href="{{ post.slug }}">
{{ post.title }}
</a>
this code above was working because you are located inside the home page and when you add this(href="{{ post.slug }}" in the a tag) it will just call the current url +"/<'slug:post_slug/' and this is a valid url.but this is a very bad option.use the the first option.
to learn about this refer to this https://docs.djangoproject.com/en/3.2/topics/http/urls/#url-namespaces.
In such cases, you should use:
https://docs.djangoproject.com/en/3.2/ref/models/instances/#get-absolute-url
The less logic in the templates, the better for the application.
It is difficult to write tests on logic that is contained in templates.
You should add a method to your model:
from django.urls import reverse
class Post()
...
def get_absolute_url(self):
return reverse('blog:blog_post', kwargs={'post_slug' : self.slug})
In the reverse function you need to add an application namespace.
In your case, it's a blog.
https://docs.djangoproject.com/en/3.2/topics/http/urls/#introduction
and then in template use:
{{ post.get_absolute_url }}
From documentation:
The logic here is that if you change the URL structure of your objects, even for something small like correcting a spelling error, you don’t want to have to track down every place that the URL might be created. Specify it once, in get_absolute_url() and have all your other code call that one place.

Why is my Django template not loading?

I have the following code which seeks to pull a number "counter" out of a DB, add a value ("+1") to it, save the new "counter" value, wait for a specified amount of time, and then start again from the beginning. This same function would be called via a view on Django, so it is also responsible for generating the template as well.
According to the development server, the function IS performing the simple arithmetic and saving the new value to the DB. As I can see the value being updated every time I refresh the Django-Admin.
However, it fails to load the template. Specifically, the page stays loading indefinitely, while the calculations happen.
Sorry if the code isn't perfect, I'm new to everything ever.
Also, please note that I have previously tested the entire ecosystem with a much simpler index function (generates simple HTML) and the template indeed generates. So I'm assuming that the problem must come from this code specifically.
Views.py:
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.template import Context, loader
from home.models import DeathNum
import datetime
import time
def index(request):
while True:
counter = DeathNum.objects.get(pk=1)
counter.deaths += 1
counter.save()
print('Added # %s ' % datetime.datetime.utcnow())
time.sleep(35)
return render(request,
'home/basenum.html',
{'number_post': str(counter)}
)
basenum.html (extending template):
{% extends "home/index.html" %}
{% block content %}
<br />
<div class="banner">
<div class="bannerNum">
<p div class="numberOf">
Number of deaths in Blank since 1999:
</p>
<br /><br /><br />
<p class="death1">
{{ number_post }}
</p>
</div>
</div>
{% endblock %}
you have to change two things in view function and queryset.
def index(request,pk):
counter = DeathNum.objects.get(pk=pk)
"""your logic here""
return render(request, 'home/basenum.html, {'number_post': str(counter)})
make sure your urlconf should be correct

Django QuerySet not appearing in HTML file for PythonAnywhere Web App

I'm having a bit of trouble with this part of the DjangoGirls tutorial (about templates).
Currently, my website is at chocoberrie.pythonanywhere.com. It's supposed to show a few posts inside the QuerySet, but the list is empty, and I don't know why (or how to fix it).
1) The QuerySet isn't loading at all in the HTML file.
I followed the steps to import the Post model into views.py and add the QuerySet in the posts variable (the previous part of the tutorial). When I tried putting {{ posts }} in the HTML file (post_list.html), nothing appears in the QuerySet that loads on the page.
2) I don't know how to edit the database file on PythonAnywhere. This database file is supposed to be separate from the local db.sqlite3 on my computer (since db.sqlite3 is in the .gitignore file, it's not committed).
I read about this here. I understand that this is useful to keep production changes from being displayed on the live website, but how I supposed to have this data on the PythonAnywhere side? What file am I supposed to edit on PythonAnywhere?
Thanks for the help, I appreciate it!
Here are my local files:
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
]
views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
post_list.html
<html>
<head>
<title>Dina's blog</title>
</head>
<body>
<div>
<h1>Dina's Blog</h1>
</div>
{{ posts }}
</body>
</html>
you cant just use the query_list like that in the template, you need to loop through it in the template and it will show all posts titles so your template will be like this
{% for post in posts %}
<p>{{post.post_title}}</p>
{% endfor %}
i recommend following this blog
I don't know if you have already done it or not, but when actually creating the posts you will also have to save it. So for example:
Example form.py
from django import forms
class createPostForm(forms.Form):
title = forms.CharField(required = True)
detail = forms.CharField(required = True)
Example views.py
import models
def createPost(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
title = form.cleaned_data.get('title')
detail = form.cleaned_data.get('detail')
newPost = models.Post(title = title, detail = detail)
newPost.save()
return redirect('blog/post_list.html')
Otherwise you won't be able to access it, since your website will take the inputs in and it will look like a post was created if the fields were valid, but your posts won't actually get created and your database will be empty! Also get a database viewer so that you can see if the entries are actually there.

How to edit dict in views.py from django admin

I'm working on a site to better learn the Django-framework. I've currently set up views and links to template files to display content on the main page. In my views.py file I've added a dictionary that is displays the dict value for each key in in the index.html page when it gets rendered:
views.py:
def Index(request):
projectmessage = {
"projectMessage":"This is text from a dictionary value. written in views.py",
"projectTitle":"Title from dict",
"projectText": "Text from dict",
}
return render(request,'wbdev/index.html', context=projectmessage)
Relevant lines in index.html:
<h3>{{ projectTitle }}</h3>
<p>{{ projectMessage }}</p>
I'm wondering if this could be made visible on the django admin page so that I can change the dict text directly from the GUI. Could this be done or am I way off in the sense that this is not the intended for the django admin page? From what I've red django admin parses the models.py file to set up text fields and buttons. I've followed the official django tutorial and some of the "How to tango with django" book but I cant wrap my head around how I should proceed in getting the functions that I want.
I'm sorry for the noob question. I will return to my books and I will probably understand how this works down the line. If anyone could help me with an explanation of how I can achieve this I will be most grateful.
Thank you.
You'll probably want to create a Model for Projects, so projects can be saved to a Database and easily displayed in the Admin.
Inside models.py include the following:
class Project(models.Model):
message = models.CharField(max_length=20)
title = models.CharField(max_length=20)
text = models.CharField(max_length=20)
Inside admin.py if you register the model it should then appear in the admin
from dajngo.contrib import admin
from .models import Project
admin.site.register(Project)
Finally for your index in views.py you'll want to query the database for the project objects in question before rendering them to the template
def index(request):
projects = Project.objects.all()
return render(request,'wbdev/index.html', context={'projects': projects})
Inside your template you can then iterate over all the projects in your database like
{% for project in projects %}
{{ project.message }}
{{ project.title }}
{{ project.text }}
{% endfor %}

django redirection issues. Objects not loaded correctly

I am trying to create a blog. Home page of the blog will contain summary about the blog posts (ordered by date).
When the user clicks on the title of the blog post on the home page, page for that post should open up.
So I am trying to the above and running into some problems.
Here is what the post.html file looks like (file that would display full post) :
{% extends "base.html" %}
{%block content %}
<div class="mainContent">
<div class = "Content">
<article class = "Typical Article">
<header>
<h3>{{post.title}}.....{{post.id}}</h3>
</header>
<footer>
<p class = "postInfo">Sukhvir Notra, {{post.date}}</p>
</footer>
<content>
<p>{{post.summary|safe|linebreaks}}</p>
</content>
</article>
</div>
</div>
{%endblock%}
And here is the urls.py file inside my app:
from django.conf.urls import patterns,include ,url
from django.views.generic import ListView, DetailView
from blog.models import blog
urlpatterns = patterns('',
url(r'^$',ListView.as_view(queryset=blog.objects.all().order_by("-date")[:20],template_name="blog.html")),
url(r'^(?P<pk>\d+)$',DetailView.as_view(model = blog,template_name="post.html")),
url(r'^archives$',ListView.as_view(queryset=blog.objects.all().order_by("-date"),template_name="archives.html")),
url(r'^latestnews$',ListView.as_view(queryset=blog.objects.all().order_by("-date")[:10],template_name="archives.html")),
)
the problem is when I click on the title on the home page, New page opens up with correct url (127.0.0.1/blog/1 --- 1 being the post.id)
but the page is blank and all I see on the page is ...... which tells me that {{post.id}},{{post.title}} variables are not working properly.
What may be causing this issue ?
Set the context_object_name in your urls to the name you want your object to have in your template.
eg:
url(r'^(?P<pk>\d+)$',DetailView.as_view(model = blog,template_name="post.html", context_object_name="post")),
Django uses a default context object with the name object (for DetailView) or object_list (for ListView) unless otherwise specified.

Categories