I am making a simple blog app in Django as a learning exercise. I am able to add posts, see them all on the front page, so it is working so far. Where I am having an issue is creating a view that shows the whole post on a separate page. I want to click the title, and go to a page at the url /post/primary key that has the title and body. When I click on the link, I get a page with just the base.html. Not sure where I am missing anything, here are urls.py, views.py, and post.html:
urls.py
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('blog.views',
url(r'^$', 'frontpage'),
url(r'^post/(\d+)/$', 'post'),
)
urlpatterns += patterns('',
url(r'^admin/', include(admin.site.urls)),
)
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404, render_to_response
from blog.models import *
views.py
def frontpage(request):
posts = Post.objects.all().order_by("-created")
paginator = Paginator(posts, 5)
page = request.GET.get('page', '1')
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = paginator.page(paginator.num_pages)
return render_to_response("list.html", dict(posts=posts, user=request.user))
def post(request, pk):
"""Single Post"""
post = Post.objects.get(pk = pk)
d = dict(post=post, user=request.user)
return render_to_response("post.html", d)
post.html
{% extends "base.html" %}
{% block content %}
<div class ="main">
<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>
</div>
{% endblock %}
Thanks in advance for your help.
I am assuming the page.html is actually the post.html you have in yoru codes sample???You no longer have a collection of posts but instead just have 1 post
This needs to change from: (which is looping through your posts)
{% extends "base.html" %}
{% block content %}
<div class ="main">
<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>
</div>
{% endblock %}
To something like (which just displays your single post):
{% extends "base.html" %}
{% block content %}
<div class ="main">
{{ post.title }}
{{ post.created }}
{{ post.body }}
</div>
{% endblock %}
You have to change urls.py to go to a page at the url /post/primary key.
urlpatterns = patterns('blog.views',
url(r'^$', 'frontpage'),
url(r'^post/(?P<pk>\d+)/$', 'post'),
)
Related
I am learning django and I really can't solve this error, I tried modifying every file but I can't find where the issue is.
Error:
OperationalError at /topics/
no such table: pizzas_topic
I have to mention that this exercise is from Python Crash Course 2nd Edition
Thanks
Here is the code from my project:
base.html:
<p>
Pizzeria -
Pizzas
</p>
{% block content %}{% endblock content %}
index.html
{% extends "pizzas/base.html"%}
{% block content %}
<p>Pizzeria</p>
<p>Hi</p>
{% endblock content%}
topic.html
{% extends 'pizzas/base.html' %}
{% block content %}
<p>Topic: {{topic}}</p>
<p>Entries:</p>
<ul>
{% for entry in entries %}
<li>
<p>{{entry.date_added|date:'M d, Y H:i'}}</p>
<p>{{entry.text|linebreaks}}</p>
</li>
{% empty %}
<li>There are no entries for this topic yet.</li>
{% endfor %}
</ul>
{% endblock content %}
topics.html
{% extends "pizzas/base.html" %}
{% block content %}
<p> Topics</p>
<ul>
{% for topic in topics %}
<li>
{{ topic }}
</li>
{% empty %}
<li>No topics have been addet yet.</li>
{% endfor %}
</ul>
{% endblock content %}
urls.py
"""Defines URL patterns for pizzeria."""
from django.urls import path
from . import views
app_name = 'pizzas'
urlpatterns = [
# Home page
path('',views.index, name='index'),
# Page that shows all pizzas.
path('topics/', views.topics, name='topics'),
# Detail page for a single topic.
path('topics/<int:topic_id>/', views.topic, name='topic'),
]
views.py
from django.shortcuts import render
from .models import Topic
def index(request):
"""The home page for Learning Log."""
return render(request, 'pizzas/index.html')
def topics(request):
"""Show all topics."""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request,'pizzas/topics.html',context)
def topic(request, topic_id):
"""Show a single topic and all its entries."""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'pizzas/topic.html', context)
Run:
python manage.py migrate
python manage.py makemigrations
python manage.py migrate
I have list of posts on my homepage, which are links to post DetailView.
Links works correctly, but when i go to DetailView, list is no more visible - i have to go back to home page to choose other post. Element which is showing posts list is located on base.html, correctly passes objects list to home.html, and in post_detail.html list is empty.
Homepage looks like this
Post DetailView looks like this - posts list is no more visible
Inspect view on homepage
Inepect view on DetailView - ul element is empty
base.html
<body>
<div>
<ul>
<li>
home
</li>
<li>
<a> items</a>
<ul>
{% for post in posts %}
<li>
{{ post.title }}
</li>
{% endfor %}
</ul>
</li>
</ul>
</div>
<di>
{% block content %}
{% endblock content %}
</div>
</body>
home.html
{% extends "blog/base.html" %}
{% block content %}
{% for post in posts %}
<div>
{{post.title}}
<p>{{post.content}}</p>
<p>{{post.date_posted}}</p>
</div>
{% endfor %}
{% endblock content %}
post_detail.html
{% extends "blog/base.html" %}
{% block content %}
<div>
{{object.title}}
<p>{{object.content}}</p>
</div>
{% endblock content %}
urls.py
from django.urls import path
from .views import PostListView, PostDetailView
from . import views
urlpatterns = [
path('', PostListView.as_view(), name='blog-home'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
]
views.py
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Post
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
class PostDetailView(DetailView):
model = Post
models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
def __str__(self):
return self.title
You have to override the context of your DetailView which display only the data of current instance.
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['other_posts'] = Post.objects.all()
return context
I'm spending hours on this thing.
I have a category page, and inside that page there's list of posts that leads to single post page if I click a particular one.
Single post page is working, single category page is working, but a page inside category page is not working, does this make sense?
def post(request, slug):#this is my view
single_post = get_object_or_404(Post, slug=slug)
single_post.views += 1 # increment the number of views
single_post.save() # and save it
t = loader.get_template('main/post.html')
context_dict = {
'single_post': single_post,
}
c = Context(context_dict)
return HttpResponse(t.render(c))
def category(request, category_name_slug):
context_dict = {}
try:
category = Category.objects.get(slug=category_name_slug)
context_dict['category_name'] = category.name
posts = Post.objects.filter(category=category)
context_dict['posts'] = posts
context_dict['category'] = category
except Category.DoesNotExist:
pass
return render(request, 'main/category.html', context_dict)
this is my url
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<slug>[\w|\-]+)/$', views.post, name='post'),
url(r'^category/(?P<category_name_slug>[\w\-]+)/$', views.category, name='category')
]
And this is my category html
{% extends 'base.html' %}
{% block content %}
<h1>{{category_name}}</h1>
{% if category %}
{%if posts %}
<ul>
{% for post in posts %}
<h3>{{ post.title }}</h3>
{% endfor %}
</ul>
{%else%}
<strong>No Pages </strong>
{% endif %}
{% else %}
{{category_name}} does not exist
{% endif %}
{% endblock %}
Finally post.html
<html>
<head>
<title></title>
<head>
<body>
<h2>{{single_post.title}}</h2>
<p>{{single_post.content}}</p>
<p> Views: {{single_post.views}}
<br>
<p>
{% if single_post.image %}
<img src="/media/{{single_post.image}}">
{% endif %}
</p>
<body>
it gives me 404 error, interesting thing is url that's giving me error is 127.0.0.1:8000/category/hello/adele but 127.0.0.1:8000/adele doesn't give me error. so inside category page, i want the access for 127.0.0.1:8000/adele –
replace {{ post.title }} with {{ post.title }}
The issue is if the reference in anchor doesnt starts with / it means its a relative url and that reference is added to current url. Hope this helps you. Also for further reference please use absolute_url feature of django. Please read this :)
Use the url template tag:
{% for post in posts %}
<h3>{{ post.title }}</h3>
{% endfor %}
This reconstruct the url based on your url configuration, ensuring it is a valid url. Here, 'post' is the name of the url you defined in your urlconf, and slug=post.slug is the parameter you pass to the capturing group in your url regex.
I was trying to add an editing/deleting function for a bookmarks app.
I get the following error:
My Urls.py file is the following:
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'myproject.views.home', name='home'),
# url(r'^myproject/', include('myproject.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'bookmarks.views.index', name='home'),
url(r'^bookmarks/$', 'bookmarks.views.index', name='bookmarks_view'),
url(r'^tags/([\w-]+)/$', 'bookmarks.views.tag'),
url(r'^login/$', 'django.contrib.auth.views.login'),
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'})
url(r'^delete/(\d+)/$', 'bookmarks.views.delete'),
url(r'^edit/(\d+)/$', 'bookmarks.views.edit'),
)
The views.py file:
...remaining code
def delete(request, bookmark_id):
if request.method == 'POST':
b = get_object_or_404(Bookmark, pk=int(bookmark_id))
b.delete()
return redirect(index)
def edit(request, bookmark_id):
b = get_object_or_404(Bookmark, pk=int(bookmark_id))
context = {
'form' : BookmarkForm(instance=b),
}
return render(request, 'edit.html', context)
The bookmark widget in index.html
{% block bookmark_widget %}
{% if request.user %}
<div id="new-bookmark-widget">
<form method="post" action="{% url bookmarks.views.index %}">
{% csrf_token %}
<h3>Bookmark</h3>
{{ form.as_p }}
<p><button id="new-bookmark-submit">Submit</button>Submit</button>
</form>
</div>
{% endif %}
{% endblock %}
The relevant div in base.html
<div id="container">
<div id="header">
{% block bookmark_widget %}
{% endblock %}
<div id="authentication">
{% if user.is_authenticated %}
Hi {{user}}! Logout
{% else %}
Login
{% endif %}
</div>
<h1>My bookmarking app</h1>
</div>
<div id="content">
<h2>{% block subheader %}{% endblock %}</h2>
{% block content %}
Sample content -- you should never see this, unless an inheriting template fails to have any content block!
{% endblock %}
</div>
<div id="footer">
All copyrights reserved
</div>
</div>
The complete bookmark.html file:
<li>
<a class="bookmark-link" href="{{ bookmark.url }}">{% if bookmark.title %}{{ bookmark.title }}{% else %}{{ bookmark.url }}{% endif %}</a>
<div class="metadata"><span class="author">Posted by {{ bookmark.author }}</span> | <span class="timestamp">{{ bookmark.timestamp|date:"Y-m-d" }}</span>
{% if bookmark.tag_set.all %}| <span class="tags">
{% for tag in bookmark.tag_set.all %}
{{ tag.slug }}</span>
{% endfor %}
{% endif %}
</div>
{% if request.user.is_authenticated %}
<div class="actions"><form method=="POST" action="{% url bookmarks.view.delete bookmark.id %}>
{% csrf_token %}
<input type="submit" value="Delete">
</form> </div>
{% endif %}
I am new to Django, how do I handle error mistakes and how do I find the problem? I couldnt see it from the error message.
Thank you!
missing a comma on the following line:
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}), <-add here
I presume your comments section also lines up with the rest of your code and it is formatted incorrectly in your question
You're missing a comma at the end of this line:
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'})
I'm new to Django and faced with next problem: when I turn on the appropriate link I get next error:
NoReverseMatch at /tutorial/
Reverse for 'tutorial.views.section_tutorial' with arguments '(1L,)' and keyword arguments '{}' not found.
What am I doing wrong? and why in the args are passed "1L" instead of "1"? (when i return "1" i get same error.) I tried to change 'tutorial.views.section_tutorial' for 'section-detail' in my template but still nothing has changed. Used django 1.5.4, python 2.7; Thanks!
tutorial/view.py:
def get_xhtml(s_url):
...
return result
def section_tutorial(request, section_id):
sections = Section.objects.all()
subsections = Subsection.objects.all()
s_url = Section.objects.get(id=section_id).content
result = get_xhtml(s_url)
return render(request, 'tutorial/section.html', {'sections': sections,
'subsections': subsections,
'result': result})
tutorial/urls.py:
from django.conf.urls import patterns, url
import views
urlpatterns = patterns('',
url(r'^$', views.main_tutorial, name='tutorial'),
url(r'^(?P<section_id>\d+)/$', views.section_tutorial, name='section-detail'),
url(r'^(?P<section_id>\d+)/(?P<subsection_id>\d+)/$', views.subsection_tutorial, name='subsection-detail'),
)
urls.py:
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^tutorial/$', include('apps.tutorial.urls')),
)
main.html:
{% extends "index.html" %}
{% block content %}
<div class="span2" data-spy="affix">
<ul id="menu">
{% for section in sections %}
<li>
{{ section.name }}
<ul>
{% for subsection in subsections%}
{% if subsection.section == section.id %}
<li><a href=#>{{ subsection.name }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</li>
</ul>
</div>
<div class="span9">
<div class="well">
{% autoescape off%}
{{ result }}
{% endautoescape %}
</div>
</div>
{% endblock %}
You don't need $ identifier in url regex in your main urls file when including app urls:
url(r'^tutorial/$', include('apps.tutorial.urls')),
should be:
url(r'^tutorial/', include('apps.tutorial.urls')),