Django blog not linking to detail view - django

I have a django blog that I'm working on and I've got the first part of the blog working in which the blog displays the various entry's from the database. However when I go to click on a particular blog post it doesn't redirect me to the detailed view, it just kinda redirects me back to the blog where I can see all the blog posts:
By clicking on this in the blog.html I want it to link to the particular post in the post.html
<h2>{{ object.title }}</h2>
urls.py
from django.conf.urls import patterns, url
from . import views, feed
urlpatterns = patterns(
'',
url(r'^feed/$', feed.LatestPosts(), name="feed"),
url(r'^', views.BlogIndex.as_view(), name="blog"),
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
)
models.py
from django.db import models
from django.core.urlresolvers import reverse
class Tag(models.Model):
slug = models.SlugField(max_length=200, unique=True)
def __str__(self):
return self.slug
class EntryQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
class Entry(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200, null=True)
body = models.TextField()
slug = models.SlugField(max_length=200, unique=True)
publish = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
tags = models.ManyToManyField(Tag)
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES, null=True, blank=True)
objects = EntryQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("entry_detail", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog Entry"
verbose_name_plural = "Blog Entries"
ordering = ["-created"]
views.py
from django.views import generic
from . import models
class BlogIndex(generic.ListView):
queryset = models.Entry.objects.published()
template_name = "blog.html"
paginate_by = 3
class BlogDetail(generic.DetailView):
model = models.Entry
template_name = "post.html"
blog.html
{% include 'head.html' %}
{% include 'navbar.html' %}
<div class="container">
{% load django_markdown %}
<br>
<br>
{% for object in object_list %}
<div class="post">
<h2>{{ object.title }}</h2>
<p class="meta"></p>
<p class="meta">
{{ object.created }} |
Tagged under {{ object.tags.all|join:", " }}
</p>
{{ object.body|markdown }}
</div>
{% endfor %}
<hr class="featurette-divider">
{% if is_paginated %}
<ul class="pager">
<li {% if not page_obj.has_previous %}class="disabled"{% endif %}><a {% if page_obj.has_previous %}href="?page={{ page_obj.previous_page_number }}"{% endif %}>Prev</a></li>
<li {% if not page_obj.has_next %}class="disabled"{% endif %}><a {% if page_obj.has_next %}href="?page={{ page_obj.next_page_number }}"{% endif %}>Next</a></li>
</ul>
{% endif %}
</div>
{% include 'footer.html' %}
post.html
{% load django_markdown %}
{% for object in object_list %}
<div class="post">
<h2>{{ object.title }}</h2>
<p class="meta">
{{ object.created }} |
Tagged under {{ object.tags.all|join:", " }} <p> Created by
{{ object.author }} </p>
</p>
{{ object.body|markdown }}
</div>
I've also got another url.py which points the blog url to all the urls in the blog app. Don't know if that helps:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'website.views.home', name='home'),
url(r'^about/', 'website.views.about', name='about'),
url(r'^contact/', 'contact.views.contact', name='contact'),
url(r'^markdown/', include("django_markdown.urls")),
url(r'^blog/', include('blog.urls')),
]

When you define the urls with this:
url(r'^', views.BlogIndex.as_view(), name="blog"),
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
The second entry matches /entry, which is not what you expect. I think that in your case, you should define it like this:
url(r'^$', views.BlogIndex.as_view(), name="blog"),
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
^$ will match /, but not /entry/...

Problem solved thanks to Brandon. Rearranged my url patterns from the most specific to the least specific (longest to shortest). And restarted the server.
urlpatterns = patterns(
'',
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
url(r'^feed/$', feed.LatestPosts(), name="feed"),
url(r'^', views.BlogIndex.as_view(), name="blog"),
)

Related

No User matches a given query Django

While trying to display post-detail template in a blog app, I get an error No User matches a given query. In my models I am inheriting from User model. What seems the problem?
# Third party imports.
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils import timezone
class Post(models.Model):
"""
Creates Model for a post in the database.
"""
title = models.CharField(max_length=100)
sub_title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
"""
A string representation of the post model.
"""
return self.title
def get_absolute_url(self):
"""
Creates the absolute url for a particular post.
"""
return reverse('blog:post-detail', kwargs={'pk': self.pk})
views.py
class PostDetailView(DetailView):
"""
View for a post's details
"""
model = Post
template_name ='blog/post_detail.html'
context_object_name = 'posts'
paginate_by = 3
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
urls.py:
# Third party imports.
from django.urls import path
from .views import (
PostListView,
PostDetailView,
PostCreateView,
PostUpdateView,
PostDeleteView,
UserPostListView,
)
# Local application imports.
from . import views
# Specifies the app's name.
app_name = "blog"
urlpatterns = [
path('', PostListView.as_view(), name='home'), # url for post list.
path('user/<str:username>/',
UserPostListView.as_view(),
name='user-posts'), # url for specific user post.
path('post/<int:pk>/',
PostDetailView.as_view(),
name='post-detail'), # url for post detail.
path('post/new/',
PostCreateView.as_view(),
name='post-create'), # url to create new post.
path('post/<int:pk>/update/',
PostUpdateView.as_view(),
name='post-update'), # url to update post.
path('post/<int:pk>/delete/',
PostDeleteView.as_view(), name='post-delete'), # url to delete post.
path('about/', views.about, name='about'), # url for about page.
]
home.html
{% extends 'blog/base.html' %}
{% load static %}
{% block crumb %}
{% for post in posts %}
<div class="post-preview">
<a href="{% url 'blog:post-detail' post.id %}">
<h2 class="post-title">{{ post.title }} </h2>
<h3 class="post-subtitle">{{ post.sub_title }} </h3>
</a>
<p class="post-meta" style="font-weight: 300;"> Posted by
<a class="text-muted">{{post.author}} on {{ post.date_posted|date:"F d, Y" }}</a>
</p>
</div>
<hr class="my-4" />
{% endfor %}
{% endblock %}
post_detail.html
{% extends "blog/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img"
src="{{ object.author.profile.image.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2"
href="{% url 'blog:user-posts' object.author.username %}">{{ object.author }}
</a>
<small class="text-muted">{{ object.date_posted|date:"F d, Y" }}</small>
{% if object.author == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1"
href="{% url 'blog:post-update' object.id %}">Update
</a>
<a class="btn btn-danger btn-sm mt-1 mb-1"
href="{% url 'blog:post-delete' object.id %}">Delete
</a>
</div>
{% endif %}
</div>
<h2 class="article-title">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
{% endblock content %}
Some notes about things that are wrong that aren't directly related to the error you're getting.
You're using a DetailView (which shows the details for a single object) where it looks like you want a ListView (to list an user's posts).
Your context_object_name is in plural, which implies you do want a list of things.
paginate_by has no effect in DetailViews, since a single-object view couldn't be paginated.
Your view refers to a blog/post_detail.html, while you've pasted in a home.html. Which one is it?
You say "In my models I am inheriting from User model.", but it looks like you're not importing a custom User model, but the default from django.contrib.auth.models import User. If you really are using a custom user model that inherits from BaseUser (not User), then that's wrong too.
The error itself, I imagine (since you're not supplying us with the traceback), comes from
user = get_object_or_404(User, username=self.kwargs.get('username'))
which means you're not passing in an <username> in the URL for that view, or the <username> you're using is incorrect (and there is no such user). (You're not showing us your urls.py, so that's just a guess.)
(A Detail view's URL, in any case, would probably not refer to an username, but the unique identifier of the post.)
EDIT
Following the edit of the original post, the issue is that the get_queryset() is simply extraneous (since no filtering by username is required) in that DetailView, so the class can be simplified to:
class PostDetailView(DetailView):
model = Post
template_name ='blog/post_detail.html'

Django form missing

So I'm trying to make a form to appear after the user is authenticated. When the user authenticated then the form appears on the home page but it never appears. I'm pretty sure I'm doing something wrong either in paths or view but can't figure this out. When I do the same code to external new template it works fine but I want the form to appear on the same page. Here is the code:
views.py
def vpn(request):
form = vpn_form(request.POST or None)
if form.is_valid():
form.save()
context ={
'form': form
}
return render(request, 'loginas/home.html', context)
urls.py
urlpatterns = [
# /
path('', views.home, name='home'),
# TEMPORARY
path('signin', views.sign_in, name='signin'),
path('signout', views.sign_out, name='signout'),
path('callback', views.callback, name='callback'),
path('', views.vpn, name='vpn'),
models.py
class VPN(models.Model):
name = models.CharField(max_length=125)
surname = models.CharField(max_length=125)
description = models.TextField()
date_to = models.DateField()
date_from = models.DateField()
forms.py
from .models import VPN
class vpn_form(forms.ModelForm):
class Meta:
model = VPN
fields = ('name', 'surname', 'description', 'date_to', 'date_from')
home template
{% extends "loginas/layout.html" %}
{% load static %}
{% block content %}
<div class="container">
<h1 class="d-flex justify-content-center"> </h1>
<p class="d-flex justify-content-center"></p>
{% if user.is_authenticated %}
<form>
{{form.as_p}}
</form>
{% else %}
<div class="d-flex justify-content-center">
Login
</div>
{% endif %}
{% endblock %}
And the page just loads empty no form present no errors in the console. Any help how to do this would be great

I want to show the topic title in the website template url link on django 3

I want to show the topic title in the website template url link on django 3.
currently opening the topic id number.
for example : http://localhost:8000/detay/4
for example : http://localhost:8000/detay/2
for example : http://localhost:8000/detay/1
but I want to do it this way
for example : http://localhost:8000/detay/1/this-is-topic-title
or
for example : http://localhost:8000/detay/3/this-is-topic-title
.
.
.
views.py
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import *
# Create your views here.
def index(request):
girdiler = Deneme1Model.objects.filter(yuklemeTarihi__lte=timezone.now()).order_by('-yuklemeTarihi')
context ={
'girdiler':girdiler
}
return render(request, 'deneme1Uygulama/index.html', context)
def ekle(request):
return render(request, 'deneme1Uygulama/ekle.html')
def detay(request, pk):
girdiler = Deneme1Model.objects.filter(pk=pk)
context ={
'girdiler':girdiler
}
return render(request, 'deneme1Uygulama/detay.html', context)
def sayfaYok(request):
return render(request, 'deneme1Uygulama/404.html')
urls.py
from django.urls import path
from .import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', views.index, name='index'),
path('ekle/', views.ekle, name='ekle'),
path('detay/<int:pk>', views.detay, name='detay'),
path('404/', views.sayfaYok, name='sayfaYok'),
]
urlpatterns +=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
from django.db import models
from django.utils import timezone
# Create your models here.
class Deneme1Model (models.Model):
baslik = models.CharField(max_length=50, verbose_name='BAŞLIK')
aKaydi = models.CharField(max_length=50, verbose_name='A KAYDI')
dosyaYukle = models.FileField(upload_to='media', verbose_name='DOSYA YÜKLE')
yuklemeTarihi =models.DateTimeField(default =timezone.now)
yayinKontrol = models.BooleanField(default=True)
def __str__(self):
return self.baslik
detay.html
{% block content %}
<div class="row">
{% if girdiler %}
{% for girdi in girdiler %}
<div class="col-12 d-flex justify-content-center">
<div class="card w-100">
<img class="card-img-top img-fluid umaxhe20" src=" {{ girdi.dosyaYukle.url }} " alt="Card image cap">
<div class="card-body">
<h5 class="card-title"> {{ girdi.baslik }} </h5>
<p class="card-text"> {{ girdi.aKaydi }} </p>
{{ girdi.yuklemeTarihi }}
</div>
</div>
</div>
{% endfor %}
{% else %}
{% url 'sayfaYok' %}
{% endif %}
</div>
{% endblock content %}
Not tested but probably something like this
urls.py
urlpatterns = [
path('detay/<int:pk>', views.detay, name='detay'),
path('detay/<int:pk>/<string:topic>', views.detay_topic, name='detay-topic'),
]
views.py
def detay_topic(request, pk, topic):
...

Diplay object list, not working

I guess that I will ask a very simple question, but it is a sign that I still do not get something.
I have a team model and I would like to display a list of all the team that the logged in user created.
I tried with
{% extends 'base.html' %}
{% block body %}
<div class="container">
<div class="jumbotron">
<h2>Select one of your team and link it to your project</h2>
</div>
<div class="col-md-8 col-md-offset-2">
{% for i in team_set.all %}
<p>{{ i.team_name }}</p>
{% endfor %}
</div>
</div>
{% endblock %}
But first it does not display anything and it is suppose to show all the team and not only the teams that the current logged in user created.
COuld you please give me a hand ?
model.py :
class Team(models.Model):
team_name = models.CharField(max_length=100, default = '')
team_hr_admin = models.ForeignKey(MyUser, blank=True, null=True)
members = models.ManyToManyField(MyUser, related_name="members")
def __str__(self):
return self.team_name
view.py:
class LinkTeam(TemplateView):
template_name= 'link_project.html'
url.py:
from django.conf.urls import url, include
from website import views
app_name = 'website'
urlpatterns = [
url(r'^hr_index/$', views.HRIndex.as_view(), name='hr_index'),
url(r'^addproject/$', views.ProjectCreate.as_view(), name='add_project'),
url(r'^addteam/$', views.TeamCreate.as_view(), name='add_team'),
url(r'^linkteam/$', views.LinkTeam.as_view(), name='Link_team'),
url(r'^project/(?P<pk>[0-9]+)/$',views.ProjectDetailView.as_view(), name='ProjectDetails'),
]
Simply, you can try this
in the View
class LinkTeam(TemplateView):
template_name= 'link_project.html'
def get(request):
courts = Yourmodel.objects.all() # worth looking into?
return render_to_response(self.template_name, {'courts': courts})
AND in HTML:
<div class="col-md-8 col-md-offset-2">
{% for i in courts %}
<p>{{ i.team_name }}</p>
{% endfor %}
</div>

Django permalink not working

models.py
from django.db import models
class Blog(models.Model):
time = models.DateTimeField(auto_now_add = True)
title = models.CharField(max_length = 100)
slug = models.SlugField()
perex = models.TextField()
content = models.TextField()
#models.permalink
def get_absolute_url(self):
return ('blog', [self.slug])
def __unicode__(self):
return self.title
class Meta:
ordering = ['-time']
views.py
from django.shortcuts import render_to_response, get_object_or_404
from blog.models import Blog
def blog_entries(request):
blogs = Blog.objects.all()[0:3]
title = "Blogs"
return render_to_response('blog/blog.djhtml', {'blogs': blogs, 'title': title,})
def blog_single_entry(request, slug):
blog = get_object_or_404(Blog, slug=slug)
title = blog.title
return render_to_response('blog/single.djhtml', {'blog': blog, 'title': title,})
url.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('',
# Examples:
# url(r'^$', 'kablog.views.home', name='home'),
# url(r'^kablog/', include('kablog.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'^blog/', 'blog.views.blog_entries', name='blog'),
url(r'^blog/(?P<slug>[-\w]+)/', 'blog.views.blog_single_entry', name='single_blog'),
)
template
{% extends 'base.djhtml' %}
{% block title %}| {{title}}{% endblock %}
{% block content %}
<div class="hero-unit">
<h1>Welcome to my Blog</h1>
<p>Where knowledge is always free</p>
<p>
<a class="btn btn-primary btn-large">
Read More
</a>
</p>
</div>
<div class="row">
{% for blog in blogs %}
<div class="span4">
<h2>{{blog}}<small>{{blog.time|date:"M D d Y"}}</small></h2>
<p>{{blog.perex|safe}}</p>
<a class="btn" href="{{ blog.get_absolute_url }}">
Read More
</a>
</div>
{% endfor %}
</div>
{% endblock %}
blog.get_absolute_url does not return a slug and also even though i have have try to browse "blog/my-first-blog" the browser just displays the home blog not the single_blog and it doesn't return a 404 error if you browse "blog/dgdsghdsfhdsfhds"
I also tried that but I can't make it work, so I try other approach
class Blog(models.Model):
[......]
#property
def get_blog_url(self):
return reverse('blog', args=[self.slug])
<a class="btn" href="{{ blog.get_blog_url }}">
Read More
</a>
You need to make #models.permalink instead #permalink.