The ERROR :
django.urls.exceptions.NoReverseMatch: Reverse for 'post_detail' with arguments '(2018, 11, 6, 'another post')' not found.
1 pattern(s) tried: ['blog\\/(?P<year>[0-9]+)\\/(?P<month>[0-9]+)\\/(?P<day>[0-9]+)\\/(?P<post>[-a-zA-Z0-9_]+)\\/$']
Here is my templates/blog/base.html file:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link href="{% static "css/blog.css" %}" rel="stylesheet">
</head>
<body>
<div id="content">
{% block content %}
{% endblock %}
</div>
<div id="sidebar">
<h2>My blog</h2>
<p>This is my blog</p>
</div>
</body>
</html>
Here is my templates/blog/post/list.html file:
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts%}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% endblock %}
And the blog/urls file:
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
#post views
path('',views.post_list,name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/',
views.post_detail,
name='post_detail'),
]
The blog/views file:
from django.shortcuts import render,get_object_or_404
from .models import Post
def post_list(request):
posts = Post.published.all()
return render(request,'blog/post/list.html',{'posts':posts})
def post_detail(request,year,month,day,post):
post = get_object_or_404(Post,slug=post,
status='published',
published__year=year,
published__month=month,
published__day = day)
return render(request,'blog/post/detail.html',{'post':post})
Please help me solve the problem, i would be very happy because i been stuck in this for a week!
Well, as you pointed that you use Django by example book then your get_absolute_url is:
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[self.publish.year,
self.publish.month,
self.publish.day,
self.slug])
There's an example how to create Post object in book:
You made a mistype and instead of slug='another-post' entered slug='another post'.
What is slug. From Django docs:
slug - Matches any slug string consisting of ASCII letters or numbers,
plus the hyphen and underscore characters. For example,
building-your-1st-django-site.
As you see, spaces are not allowed in slug.
You can delete your post with incorrect slug and create another object.
Or you can fix existing post directly in shell:
from django.utils.text import slugify
post = Post.objects.get(pk=id_of_your_post) # replace with int number
fixed_slug = slugify(post.slug)
post.slug = fixed_slug
post.save()
Related
In my code below all the questions & related images stored in my table are coming on same page at one go but I want only first question and its image to appear and than when user clicks on next button the second question along with its image should come, this should repeat till end of records in the table.
View
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from quiz.models import Quiz, Question
def playQuiz(request):
data=Question.objects.filter(__isnull=False)
res=render(request,'quiz/quiz_play.html',{'data':data})
return res
Template
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% for data in data %}
<div><h1> {{data.qs}} </h1></div>
<div> <img src="{{ data.qip.url }}" height=300> </div>
<input type="button" name="next-btn" value="NEXT">
{% endfor %}
</body>
</html>
You can use a Paginator to achieve this. It will automatically handle the going forward or backward.
from django.shortcuts import render
from django.core.paginator import Paginator
from quiz.models import Quiz, Question
def playQuiz(request):
data=Question.objects.filter(__isnull=False)
paginator = Paginator(data, 1) # Show 1 data per page.
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
res = render(request, 'quiz/quiz_play.html', {'page_obj': page_obj})
return res
In your template you will use it like this.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% for data in page_obj %}
<div><h1> {{data.qs}} </h1></div>
<div> <img src="{{ data.qip.url }}" height=300> </div>
<input type="button" name="next-btn" value="NEXT">
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
</body>
</html>
If one wanted to operate the on the "next_object" what would need to be done to the code below to allow for the objects or an id of the object to be passed back to "send_and_receive():" with a post method?
For the sake of the people who want to immediately close this as a duplicate of referencing in an insecure way, I am asking for doing this with POST not GET.
routes.py code
#app.route('/statistics', methods=['POST'])
def send_and_receive():
reference_form = ReferenceForm()
if reference_form.object_approved.data:
library.approve_object(??reference_object_id_or_object??)
return redirect('index')
if reference_form.object_rejected.data:
library.reject_object(??reference_object_id_or_object??)
return redirect('index')
next_object = library.get_next()
return render_template('site.html', reference_form=reference_form, next_object=next_object)
site.html
{% extends "base.html" %}
{% block content %}
<form action="" method="post">
<p>{{next_object.string()}}</p>
<p>{{ reference_form.object_approved() }}</p>
<p>{{ reference_form.object_rejected() }}</p>
</form>
{% endblock %}
Forms.py code
class ReferenceForm(FlaskForm):
object_approved = SubmitField("Approve")
object_rejected = SubmitField("Reject")
Make sure that you set the app's SECRET_KEY and render out the hidden fields in the html template, including the automatically added (see documentation) csrf_token hidden field.
A simple example:
app.py
from flask import Flask, render_template, flash
from flask_wtf import FlaskForm
from wtforms import SubmitField, HiddenField
class ReferenceForm(FlaskForm):
object_id = HiddenField()
object_approved = SubmitField("Approve")
object_rejected = SubmitField("Reject")
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456790'
#app.route('/', methods=['GET', 'POST'])
def index():
_form = ReferenceForm()
_form.object_id.data = 42
if _form.validate_on_submit():
flash('Object ID:{}'.format(_form.object_id.data))
print(_form.object_approved.data)
print(_form.object_rejected.data)
print(_form.object_id.data)
# process form blah blah
# would be usual to return a redirect here
return render_template('index.html', reference_form=_form)
if __name__ == '__main__':
app.run()
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form action="" method="post">
{{ reference_form.object_id() }}
{{ reference_form.csrf_token() }}
<p>{{ reference_form.object_approved() }}</p>
<p>{{ reference_form.object_rejected() }}</p>
</form>
</body>
</html>
Note how the html gets rendered, especially the two hidden fields, object_id and csrf_token:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<input id="object_id" name="object_id" type="hidden" value="42">
<input id="csrf_token" name="csrf_token" type="hidden" value="IjBjNGIwNWE2NDA5NDVmZjhiMjU3Y2E5YTIwY2QwMGVlMTMxYzViYzUi.X0oupA.g9KjI79vZvfEIW1mwzR7nvHc6Yc">
<p><input id="object_approved" name="object_approved" type="submit" value="Approve"></p>
<p><input id="object_rejected" name="object_rejected" type="submit" value="Reject"></p>
</form>
</body>
</html>
Model defined in the header of my pages appears on page load and refresh on the main page, but when I navigate to another view the model doesn't appear there. The rest of the header is there, just the dynamic data that isn't.
Where am I going wrong? New to both Python and Django, so if anyone can help, please don't be afraid to patronize and Eli5 :)
Model defined in models.py:
from django.db import models
from django.utils import timezone
# Create your models here.
class Propaganda(models.Model):
slogan = models.CharField(max_length=140, blank=True, null=True)
def __str__(self):
return self.slogan
header.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Christopher's weblog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Blog site.">
<!-- Let's get the static files where we use them, but this could be before the html tag -->
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'blog/css/bulma.css' %}" type="text/css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- <link rel="stylesheet" href="{% static 'blog/css/cupar.css' %}" type="text/css" /> -->
</head>
<body>
<section class="hero is-success is-bold">
<div class="hero-body">
<div class="container">
{% block slogan %}
{% for propaganda in propagandas %}
<h6>{{ propaganda.slogan }} it's</h6>
{% endfor %}
{% endblock %}
<h1 class="title" style="display: inline-block;">
<span class="icon">
<i class="fa fa-home"></i>
</span>
The Guide
</h1>
{% if user.is_authenticated %}
<div class="field">
<div class="control">
<a href="{% url 'post_new' %}" class="button is-warning is-pulled-right">
<span class="icon">
<i class="fa fa-plus-square"></i>
</span>
<span>New post</span>
</a>
</div>
</div>
{% endif %}
</div><!-- #container -->
</div>
</section>
<!-- content under header in here-> -->
{% block content %}
{% endblock %}
</body>
</html>
views.py
from django.template import RequestContext
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post, Propaganda
from .forms import PostForm
from django.utils import timezone
# Create your views here.
def post_list(request):
posts = Post.objects.all()
propagandas = Propaganda.objects.all().order_by('?')[:1]
return render(request, 'blog/post_list.html', {'posts': posts, 'propagandas': propagandas})
post_detail.html (where the model does not appear):
{% extends 'blog/header.html' %}
{% block content %}
some html / form that has nothing to do with the header.
{% endblock %}
post_list.html (the 'index' page where the model works fine)
{% extends "blog/header.html" %}
{% block content %}
{% for post in posts %}
<section class="section">
more html
{% endblock %}
need to pass the data from each view function that is required in the header you are extending (re-using) in each template.
def post_detil(request, id):
posts = Post.objects.all()
propagandas = Propaganda.objects.all().order_by('?')[:1]
# ... add in other stuff relevant to post details ...
post = Post.objects.get(pk=id)
return render(request, 'blog/post_detail.html', {'posts': posts, 'propagandas': propagandas, 'post': post})
Stick with it #Rin and Len, you'll get there :)
First: Why are you not showing the view of post_detail. Isn't that the one that does not work?
Second: Even though you are extending a base template you still have to pass the appropriate context in order to generate the desired dynamic data.
I hope it helps.
I am new with Django and trying to understand how to use templates and I have an issue with template extending. I have 3 templates. the first one in the base.html
{% load staticfiles%}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" type="text/css" href="{%static 'css/main.css'%}">
<title>Home</title>
</head>
<body >
<div class="page-header">
<h1>Django Project</h1>
</div>
<div class="content container">
<div class="row">
<div class="col-sm-8">
{%block content %}
{%endblock%}
</div>
<div class="col-sm-4">
{%block lastposts %}
{%endblock%}
</div>
</div>
</div>
</body>
</html>
Second one is post_list.html (which I render from views)
{% extends 'blog/base.html' %}
{% block content %}
{%for post in posts %}
<h1>{{post.title}}</h1>
<p>{{post.text|linebreaks}}</p>
<p><b>Author: </b>{{post.author}}</p>
<p><b>Published Date: </b>{{post.published_date}}</p>
{%endfor%}
{% endblock %}
and latest_posts.html
{% extends 'blog/base.html' %}
{% block lastposts %}
<h3>Latest Posts</h3>
{%for post in posts%}
<h4>{{post.title}}</h4>
{% endfor %}
{% endblock %}
The problem is that the content of latest_posts.html does not show up. I know that something is wrong. In that case how I can use extending in django to to separate my code in these 3 files. Thanks.
*UPDATE
views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
# Create your views here.
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})
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
]
If you want to display the contents of latest_posts.html in post_list.html, you'll have to include it
post_list.html
{% extends 'blog/base.html' %}
{% block content %}
{%for post in posts %}
<h1>{{post.title}}</h1>
<p>{{post.text|linebreaks}}</p>
<p><b>Author: </b>{{post.author}}</p>
<p><b>Published Date: </b>{{post.published_date}}</p>
{%endfor%}
{% endblock %}
{%block lastposts %}
{% include 'blog/latest_posts.html' %}
{% endblock %}
latest_posts.html (only remove the extend and block tags)
<h3>Latest Posts</h3>
{%for post in posts%}
<h4>{{post.title}}</h4>
{% endfor %}
I realise I'm doing something basic wrong here, just not sure what it is. I'm not getting any errors, but I'm not getting any of the model data displayed when I load the page.
Here's what I'm trying to do:
Apps: base, blog, resume
I'm trying to get the models from blog and resume to show up in the view of base. Both the blog and resume apps work fine on their own.
base/views.py
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response
from testpro.blog.models import Post
from testpro.resume.models import Project
def main(request):
"""Main listing."""
posts = Post.objects.all().order_by("-created")
projects = Project.objects.all().order_by("-created")
return render_to_response("list.html", dict(posts=posts, projects=projects, user=request.user))
list.html template
{% extends "bbase.html" %}
{% block content %}
<div class="main">
<h3>Blog Posts</h3>
<!-- Posts -->
<ul>
{% for post in posts.object_list %}
<div class="title">{{ post.title }}</div>
<ul>
<div class="time">{{ post.created }}</div>
<div class="body">{{ post.body|linebreaks }}</div>
</ul>
{% endfor %}
</ul>
<!-- Projects -->
<h3>Projects</h3>
<ul>
{% for project in projects.object_list %}
<div class="title">{{ project.title }}</div>
<ul>
<div class="industry">{{ project.industry }}</div>
<div class="time">{{ project.created }}</div>
<div class="body">{{ project.body|linebreaks }}</div>
</ul>
{% endfor %}
</ul>
</div>
{% endblock %}
finally, urls.py
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^main/', 'base.views.main'),
(r'^admin/', include(admin.site.urls)),
)
What stupid mistake am I making? The template renders, it just doesn't contain any model data.
Edit: Added bbase.html template
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <title>{% block title %}Test Project{% endblock %}</title> </head>
<body>
<div id="sidebar"> {% block sidebar %} {% endblock %} </div>
<div id="container">
<div id="menu">
{% block nav-global %}
<!-- MENU -->
<h3>MyBlog</h3>
{% if user.is_staff %}
Admin
Add post
{% endif %}
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</div>
</body>
</html>
{% for project in projects.object_list %}
# should be
{% for project in projects %}
and
{% for post in posts.object_list %}
# should be
{% for post in posts %}
QuerySets don't have an object_list attribute I'm aware of, so the template engine is silently failing on it.