Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/detail/python
Raised by: main.views.blog_detail
No Blog matches the given query.
It says that the error is raised by "main.views.blog_detail", What am I missing or what could be the erroe?
This is my urls.py:
from django.urls import path
from . import views
app_name = 'main'
urlpatterns = [
path('' , views.test , name='test_view'),
path('blog/', views.blog_list, name='blog_list'),
path('<slug:category_slug>' , views.blog_list , name='blog_list'),
path('detail/<slug:blog_slug>' , views.blog_detail , name='blog_detail'),
]
This is my views.py file:
from django.shortcuts import render
from django.http import HttpResponse
from .models import Blog,BlogCategory
from django.shortcuts import get_object_or_404
# Create your views here.
def test(request):
template = 'base.html'
# context = {'product_list':productlist, 'category_list':categorylist, 'category':category}
return render(request, template)
def blog_list(request, category_slug=None):
category = None
bloglist = BlogCategory.objects.all()
if category_slug:
category = get_object_or_404(BlogCategory,slug=category_slug)
bloglist = bloglist.filter(category=category)
template = 'main/blog.html'
context = {'blog_list':bloglist}
return render(request, template, context)
def blog_detail(request, blog_slug):
print(blog_slug)
blogdetail = get_object_or_404(Blog, slug=blog_slug)
template = 'Main/blog_details.html'
context = {'blog_detail':blogdetail}
return render(request, template, context)
This is my models.py file:
from django.db import models
from datetime import datetime
from django.utils.text import slugify
# Create your models here.
class Blog(models.Model):
blog_title = models.CharField(max_length=200)
blog_content = models.TextField()
blog_published = models.DateTimeField('date published', default=datetime.now)
blog_category = models.ForeignKey('BlogCategory', on_delete=models.SET_NULL, null=True)
slug = models.SlugField(blank=True,null=True)
def save(self, *args, **kwargs):
if not self.slug and self.blog_title:
self.slug = slugify(self.blog_title)
super(Blog,self).save(*args, **kwargs)
def __str__(self):
return self.blog_title
class BlogCategory(models.Model):
blog_category = models.CharField(max_length=200)
blog_summary = models.CharField(max_length=200)
slug = models.SlugField(blank=True,null=True)
def save(self, *args, **kwargs):
if not self.slug and self.blog_category:
self.slug = slugify(self.blog_category)
super(BlogCategory,self).save(*args, **kwargs)
class Meta:
# Gives the proper plural name for admin
verbose_name_plural = "Categories"
def __str__(self):
return self.blog_category
This is my bloglist.html:
{% extends 'base.html' %}
{% block content %}
<div class="row">
{% for bl in blog_list %}
<div class="col s12 m6">
<a href="{% url 'main:blog_detail' bl.slug %}">
<div class="card hoverable">
<div class="card-content">
<span class="card-title">{{bl.blog_category}}</span>
<p style="font-size:70%">Published {{bl.blog_published}}</p>
<p>{{bl.blog_summary}}</p>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
This is my blogdetails.html:
{% extends 'base.html' %}
{% block content %}
<div class="row">
<div class="col s12, m8, l8">
<h3>{{blog_detail.blog_title}}</h3>
<p style="font-size:70%">Published {{blog_detail.blog_published}}</p>
{{blog_detail.blog_content|safe}}
</div>
</div>
{% endblock %}
You have to just change a name of 'Main' to 'main' because your blog_details.html page was in main directory. And also check name of blog_details.html directory properly than integrate it properly with perfect name.
template = 'main/blog_details.html'
Related
When I add a | slugify in the home.html I get this error if I don't add everything works fine.
Also when I enter a category, posts are not displayed in some categories, there is no post in this category is displayed. There are also critical errors constantly pop out, perhaps there is a bug somewhere or not the correct code, I still did not find the reason, I solve one second, an error pops out
models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
#from datetime import datetime, date
from django.utils import timezone
class Category(models.Model):
name=models.CharField(max_length=255)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('home')
class Post(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
post_date = models.DateTimeField(auto_now_add=True)
category = models.CharField(max_length=200, default='разные')
def __str__(self):
return self.title + ' | ' + str(self.author)
def get_absolute_url(self):
return reverse('article_detail', args=[str(self.id)])
views.py
from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post, Category
from .forms import PostForm, EditForm
from django.urls import reverse_lazy
#def home(request):
# return render(request, 'home.html', {})
class HomeView(ListView):
model = Post
cats = Category.objects.all()
template_name = 'home.html'
ordering = ['-post_date']
def get_context_data(self, *args, **kwargs):
cat_menu = Category.objects.all()
context = super(HomeView,self).get_context_data(*args, **kwargs)
context["cat_menu"] = cat_menu
return context
def CategoryView(request, cats):
category_posts = Post.objects.filter (category = cats)
return render(request, 'categories.html', {'cats':cats.title(), 'category_posts':category_posts})
class ArticleDetailView(DetailView):
model = Post
template_name = 'post_detail.html'
class AddPostView(CreateView):
model = Post
form_class = PostForm
template_name= 'add_post.html'
#fields = '__all__'
class AddCategoryView(CreateView):
model = Category
template_name= 'add_category.html'
fields = '__all__'
class UpdatePostView(UpdateView):
model = Post
template_name = 'update_post.html'
form_class = EditForm
#fields = ['title', 'body']
class DeletePostView(DeleteView):
model = Post
template_name = 'delete_post.html'
success_url = reverse_lazy('home')
home.html
{% extends 'base.html' %}
{% block content %}
<h1>Articles</h1>
{% for post in object_list %}
<ul>
<li>
<h2><l1>{{ post.title }}</h2>
{{ post.category }}
| {{ post.author }}
{% if user.is_authenticated %}
|-<small>Редакт..)</small>
{% endif %}
<br/>{{ post.body|slice:":50"|safe }}
</l1>
</ul>
{% endfor %}
{% endblock %}
urls.py
from django.urls import path
from .views import HomeView, ArticleDetailView, AddPostView, UpdatePostView, DeletePostView, AddCategoryView, CategoryView
urlpatterns = [
path('', HomeView.as_view(), name='home'),
path('article/<int:pk>', ArticleDetailView.as_view(), name='article_detail'),
path('add_post/', AddPostView.as_view(), name='add_post'),
path('add_category/', AddCategoryView.as_view(), name='add_category'),
path('article/edit/<int:pk>', UpdatePostView.as_view(), name='update_post'),
path('article/<int:pk>/delete', DeletePostView.as_view(), name='delete_post'),
path('category/<str:cats>/', CategoryView, name='category'),
]
categories.py
{% extends 'base.html' %}
{% block content %}
{% if category_posts %}
<h1>{{cats}}</h1>
{% for post in category_posts %}
<ul>
<l1>{{ post.title }}
| {{ post.author }}
{% if user.is_authenticated %}
|-<small>Редакт..)</small>
{% endif %}
<br/>{{ post.body|slice:":50"|safe }}
</l1>
</ul>
{% endfor %}
{% else %}
<h1>So sorry</h1>
{% endif %}
{% endblock %}
Please help me on the map of my training and suggest a solution to my fatal errors
I am trying to pass some wagtail contexts to the search page of a django project. The post title appears but the image, description and other parameters do not appear in the search template. How do I pass these contexts to the search template?
This is the error I get
AttributeError at /search/
'str' object has no attribute 'relative_url'
Request Method: GET
Request URL: http://127.0.0.1:8000/search/?q=hel
Django Version: 3.1.3
Exception Type: AttributeError
Exception Value:
'str' object has no attribute 'relative_url'
Exception Location: C:\Users\Bree\AppData\Roaming\Python\Python37\site-packages\wagtail\contrib\routable_page\templatetags\wagtailroutablepage_tags.py, line 25, in routablepageurl
Python Executable: C:\Program Files\Python37\python.exe
Python Version: 3.7.3
This is the search.view.py code
from django.shortcuts import render
from wagtail.core.models import Page
from wagtail.search.models import Query
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from news.models import NewsPage, NewsCategory
def search(request):
posts = NewsPage.objects.live().public()
categories = NewsCategory.objects.all()
# Search
search_query = request.GET.get('q', None)
if search_query:
search_results = NewsPage.objects.live().search(search_query)
# Log the query so Wagtail can suggest promoted results
Query.get(search_query).add_hit()
reversenews = list(reversed(search_results))
# Pagination
paginator = Paginator(reversenews, 16) #show 10 articles per page
page = request.GET.get('page')
try:
search_results = paginator.page(page)
except PageNotAnInteger:
search_results = paginator.page(1)
except EmptyPage:
search_results = paginator.page(paginator.num_pages)
else:
search_results = NewsPage.objects.none()
# Render template
return render(request, 'search/search.html', {
'search_query': search_query,
'search_results': search_results,
'recent_posts' : posts,
'categories' : categories
})
this is the search template search.html
{% extends "news/news_index_page.html" %}
{% load static wagtailcore_tags %}
{% load wagtailembeds_tags %}
{% load wagtailcore_tags %}
{% load static wagtailuserbar %}
{% load wagtailimages_tags %}
{%load static%}
{% load wagtailcore_tags %}
{% load wagtailroutablepage_tags %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-8">
<h3>Query Results FOR <b>"{{ search_query }}"</b></h3>
<div class="post">
{% if search_results %}
<div class="row">
{% for result in search_results %}
<div class="col-md-6 col-sm-6">
<div class="images">
{% image result.blog_image max-770x480 as blog_img %}
<a class="images" href="{% pageurl result %}" title="images"><img src="{{result.blog_image}}" alt="images"></a>
</div>
<div class="text">
<h2>{{result.title}}</h2>
<div class="categories">
{% for cat in result.categories.all%}
{{cat.name}}
{%endfor%}
<p class="date"><i class="fa fa-clock-o"></i>{{result.date}}</p>
</div>
<p>{{result.description}}</p>
read more
</div>
{%endfor%}
</div>
{% elif search_query %}
<p> No results found</p>
<img src="{% static '/images/not_found %}" alt="image">
{% endif %}
</div>
<!-- Pagination -->
{% if search_results.paginator.num_pages > 1 %}
<div class="box center float-left space-30">
<nav class="pagination">
{% if search_results.has_previous %}
<a class="control prev" href="?page={{ search_results.previous_page_number }}" title="pre"><i class="fa fa-long-arrow-left"></i>Previous</a>
{% endif %}
<ul>
{% for page_num in search_results.paginator.page_range %}
<li class="{% if page_num == search_results.number %} active{% endif %}">{{ page_num }}</li>
{% endfor %}
</ul>
{% if search_results.has_next %}
<a class="control next" href="?page={{ search_results.next_page_number }}" title="next">Next<i class="fa fa-long-arrow-right"></i></a>
{% endif %}
</nav>
<!-- End pagination -->
</div>
{% endif %}
</div>
</div>
This is the models.py
from django.db import models
from django.shortcuts import render
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel, MultiFieldPanel, InlinePanel
from wagtail.snippets.edit_handlers import SnippetChooserPanel
from wagtail.core.fields import StreamField
from wagtail.core.models import Page, Orderable
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.snippets.models import register_snippet
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from wagtailmenus.models import MenuPage
from django import forms
import datetime
from datetime import date
from streams import blocks
# Create your models here.
class NewsPageTag(TaggedItemBase):
content_object = ParentalKey(
'NewsPage',
related_name='tagged_items',
on_delete=models.CASCADE
)
class NewsIndexPage(RoutablePageMixin, Page):
custom_title = models.CharField(
max_length=100,
blank=True,
null=True,
help_text='Overwrites the default title',
)
content_panels = Page.content_panels + [
FieldPanel("custom_title"),
]
def get_context(self, request, *args, **kwargs):
"""Adding custom stuff to our context."""
context = super().get_context(request, *args, **kwargs)
posts = NewsPage.objects.live().public()
context["recent_posts"] = posts
context["tech_world"] = NewsPage.objects.live().filter(categories = 2)
context["digital_creatives"] = NewsPage.objects.live().filter(categories = 10)
context["exclusives"] = NewsPage.objects.live().filter(categories = 4)
context["news"] = NewsPage.objects.live().filter(categories = 1)
context["startups"] = NewsPage.objects.live().filter(categories = 3)
context['news_page'] = self
context['parent'] = self.get_parent().specific
context['categories'] = NewsCategory.objects.all()
return context
#route(r"^category/(?P<cat_slug>[-\w]*)/$", name="category_view")
def category_view(self, request, cat_slug):
context = self.get_context(request)
try:
category = NewsCategory.objects.all().get(slug=cat_slug)
except Exception:
category= None
if category is None:
pass
catPosts = NewsPage.objects.all().filter(categories__in=[category])
reversenews = list(reversed(catPosts))
paginator = Paginator(reversenews, 6)
page = request.GET.get("page")
try:
# If the page exists and the ?page=x is an int
posts = paginator.page(page)
except PageNotAnInteger:
# If the ?page=x is not an int; show the first page
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
context["posts"]= posts
context["category"] = NewsCategory.objects.all().get(slug=cat_slug)
return render(request, "news/cat_posts.html", context)
class NewsPage(Page):
"""Blog detail page."""
blog_image = models.ForeignKey(
"wagtailimages.Image",
blank=False,
null=True,
related_name="+",
on_delete=models.SET_NULL,
)
image_description = models.TextField(max_length=500, blank=True, null=True , default=" ")
categories = ParentalManyToManyField("news.NewsCategory", blank = True)
date = models.DateTimeField(verbose_name="Post date", default=datetime.datetime.today)
tags = ClusterTaggableManager(through=NewsPageTag, blank=True)
content = StreamField(
[
("full_richtext", blocks.RichtextBlock())
],
null=True,
blank=False
)
description = StreamField(
[
("full_richtext", blocks.RichtextBlock())
],
null=True,
blank=False
)
content_panels = Page.content_panels + [
MultiFieldPanel([
InlinePanel("news_authors", label="Author", min_num=1, max_num=4)
], heading="Author(s)"),
MultiFieldPanel([
FieldPanel("categories", widget = forms.CheckboxSelectMultiple),
FieldPanel('tags'),
FieldPanel('date'),
]),
ImageChooserPanel("blog_image"),
FieldPanel('image_description'),
StreamFieldPanel("content"),
StreamFieldPanel("description"),
]
#property
def news_page(self):
return self.get_parent().specific
def get_context(self, request, *args, **kwargs):
context = super(NewsPage, self).get_context(request, *args, **kwargs)
posts = NewsPage.objects.live().public()
context['categories'] = NewsCategory.objects.all()
context['news_page'] = self.news_page
context['post'] = self
context["recent_posts"]= NewsPage.objects.live().public()
return context
class NewsAuthor(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=500, blank=False, null=True)
email = models.URLField(blank=True, null=True)
image = models.ForeignKey(
"wagtailimages.Image",
on_delete=models.SET_NULL,
null = True,
blank = False,
related_name="+"
)
panels = [
MultiFieldPanel([
FieldPanel("name"),
FieldPanel("description"),
ImageChooserPanel("image")
], heading="Name & Image"),
MultiFieldPanel([
FieldPanel("email")
], heading="Links")
]
def __str__(self):
return self.name
register_snippet(NewsAuthor)
class NewsCategory(models.Model):
name= models.CharField(max_length=255)
slug = models.SlugField(
verbose_name="slug",
allow_unicode= True,
unique=True,
max_length=255,
help_text="A slug to identify posts by this category"
)
panels=[
FieldPanel("name"),
FieldPanel("slug")
]
class Meta:
verbose_name = 'News Category'
verbose_name_plural = 'News Categories'
ordering = ['name']
def __str__(self):
return self.name
register_snippet(NewsCategory)
This is the urls.py
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
from search import views as search_views
urlpatterns = [
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/$', search_views.search, name='search'),
]
What am I doing wrong?
It seems like the news_page variable in your template is a string, rather than a page object, as that's the only use of the {% routablepageurl %} tag in the code examples you have shared. However, you don't show where news_page is defined, so I may be mistaken.
I have now looked at your models file, and where you define news_page. You have defined news_page in the context of NewsIndexPage. This will be used when displaying a NewsIndexPage, using Wagtail's internal views, but this is not used when rendering the search view.
Here's the response context you are setting in your search/views.py:
# Render template
return render(request, 'search/search.html', {
'search_query': search_query,
'search_results': search_results,
'recent_posts' : posts,
'categories' : categories
})
Can you add news_page to the context there?
I have made a script to display all posts in a category so, when I try to open the single category it didn't open the page and show the article page, I've followed a tutorial for making this code, the link is: https://www.youtube.com/watch?v=o6yYygu-vvk .
Models.py
from django.db import models
from django import forms
from django.contrib.auth.models import User
from django.urls import reverse
# Categorie
class Category(models.Model):
class Meta:
verbose_name = 'category'
verbose_name_plural = 'categories'
name = models.CharField('Titolo', max_length = 250)
slug = models.SlugField(max_length = 250, unique = True)
desc = models.TextField('Descrizione', max_length=10000, blank=True)
def get_absolute_url(self):
return reverse("blog:CategoryList", args=[self.slug])
def __str__(self):
return self.name
# Articles
class Article(models.Model):
class Meta:
verbose_name = 'Articolo'
verbose_name_plural = 'Articoli'
'''
Classe per creare articoli generali con media
'''
title = models.CharField('Titolo', max_length=100)
author = models.ForeignKey(User, on_delete=models.CASCADE,)
category = models.ForeignKey (Category, on_delete=models.CASCADE)
desc = models.CharField('Descrizione', max_length=10000, blank=True)
text = models.TextField('Testo', max_length=10000, blank=True)
image = models.ImageField('Foto', blank=True, upload_to="img")
data = models.DateTimeField('Data di pubblicazione', blank=True)
slug = models.SlugField(max_length = 250, null = True, blank = True, unique=True)
class Meta: # Order post by date
ordering = ['-data',]
def __str__(self):
return "Crea un nuovo articolo"
Views.py
from django.shortcuts import render, get_object_or_404
from django.shortcuts import render
from django.http import HttpResponse
from .models import *
from django.views.generic import View
from django.views import generic
def index(request): # HomePage
articles = Article.objects.all().order_by('-data')[0:3] # Show last 3 articles
return render(request, 'blog/index.php', {'articles':articles})
# Post
def PostList(request): # Articles List
articles = Article.objects.all().order_by('-data')
return render(request, 'blog/post/PostList.php',{'articles':articles})
class PostDetail(generic.DetailView): #Single Article
model = Article
template_name = 'blog/post/post_detail.php'
# Category
def Categories(request): # Category List
categories = Category.objects.all()
return render(request, 'blog/category/category.php',{'categories':categories})
def CategoryList(request, slug): # Show post by category
categories = Category.objects.all()
articles = Article.objects.all()
if slug:
category = get_object_or_404(Category, slug=slug)
articles = articles.filter(category=slug)
template = 'blog/category/single_category.php'
context = {'categories':categories, 'articles':articles, 'category': category}
return render(request, template, context)
Urls.py
from django.conf.urls import url
from . import views
from django.contrib import admin
from django.views.generic import ListView, DetailView
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name='index'), # Index
url(r'^all-articles$', views.PostList, name='PostList'), # All Posts
url(r'^category', views.Categories, name='category'), # All Category
url('<slug: slug>/', views.CategoryList, name='category_list'), # Show post by category
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'), # Single Posts
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()
post_detail.php
{% extends 'blog/layout.php' %} <!-- Import Content -->
{% block content %} <!-- Start Content -->
<!-- Articles -->
<div class="article">
{% if article.image %}
<img src="{{article.image.url}}" alt="" class="">
{% endif %}
<div class="article__text">
<h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
<p class="article_info"> Scritto da {{ article.author }} il {{
article.data }}</p>
<p class=" article_desc">{{ article.desc }}</p>
<p class=" article_content">{{ article.text }}</p>
<p class=" article_category">category: <a href="{{ articles.category.get_absolute_url
}}">
{{ article.category }}</a></p>
</div>
</div>
{% endblock content %}
single_category.php
{% extends 'blog/layout.php' %} <!-- Import Content -->
<!-- Content -->
{% block content %}
<h1>{{ category.name }}</h1>
{% for article in articles %}
<!--CARDS -->
<section class="cards"clearfix> <a href="{% url 'post_detail' article.slug %}">
<div class="card">
{% if article.image %}
<img src="{{article.image.url}}" alt="" class="card__img">
{% endif %}
<div class="card__txt">
<h3 class="card__title">{{article.title}}</h3>
<p class="date__article"> by {{article.author}}</p>
<p class="card__text">{{article.desc}}</p>
</div>
</div>
</a>
</section>
{% endfor %}
{% endblock %}
Your function to return the url of category is wrong because the name of "CategoryList" don't exists in
class Category():
#---- your properties definition
def get_absolute_url(self):
#bad return reverse("blog:CategoryList", args=[self.slug])
return reverse("blog:category_list", args=[self.slug])
In your urls.py
url('<slug: slug>/', views.CategoryList, name='category_list'), # Show post by category
category_list is defined as name in your url, not ~CategoryList~
AND
You use the same URL for post and category list
url('<slug: slug>/', views.CategoryList, name='category_list'), # Show post by category
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
AND You are mixing url and path in the same definition.
So, you probably are use django 2.x and read django 1.x tutorial.
Another think (that the devs was commented)... the extension of html files as php is not good, php is a "program language" and html is another thing... but, you can use any extension...
I am trying to use slug as url in post detail. But this gives me error like this
.It says error is realted to posts.view.detail when my database is empty. but after adding few posts from admin interface i get error something like this
What is wrong here?
NoReverseMatch at /posts/
Reverse for 'detail' with keyword arguments '{'id': 1}' not found. 1 pattern(s) tried: ['posts/(?P[^/]+)/$']
posts/models.py
from django.db import models
from django.urls import reverse
from django.db.models.signals import pre_save
from django.utils.text import slugify
# Create your models here.
def upload_location(instance, filename):
#filebase, extension = filename.split(".")
# return "%s/%s.%s" %(instance.id,instance.id, extension)
return "%s/%s" %(instance.id, filename)
class Post(models.Model):
title = models.CharField(max_length= 120)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to=upload_location,
null=True,
blank = True,
width_field="width_field",
height_field="height_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = models.TextField()
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.title
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"slug": self.slug})
#return "/posts/%s/" %(self.id)
class Meta:
ordering: ["-timestamp", "-updated"]
def create_slug(instance, new_slug=None):
slug = slugify(instance.title)
if new_slug is not None:
slug = new_slug
qs = Post.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" %(slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
pre_save.connect(pre_save_post_receiver, sender=Post)
posts/urls.py
from django.urls import path
from .views import (
posts_create,
posts_delete,
posts_detail,
posts_list,
posts_update
)
app_name = "posts"
urlpatterns = [
path("", posts_list, name="list"),
path("<slug>/", posts_detail, name="detail"),
path("create/", posts_create, name="create"),
path("<slug>/edit/", posts_update, name="update"),
path("<slug:slug>/delete/", posts_delete, name="delete"),
]
posts/view.py
def posts_detail(request, slug=None):
#instance = Post.objects.get(id=1)
instance = get_object_or_404(Post, slug=slug)
context = {
"title": instance.title,
"instance": instance
}
return render(request, "post_detail.html", context)
def posts_list(request):
queryset_list = Post.objects.all()
paginator = Paginator(queryset_list, 5)
page_request_var= "page"
page = request.GET.get(page_request_var)
try:
queryset = paginator.page(page)
except PageNotAnInteger:
queryset = paginator.page(1)
except EmptyPage:
queryset = paginator.page(paginator.num_pages)
#contacts = paginator.get_page(page)
context = {
"object_list": queryset,
"title": "List",
"page_request_var": page_request_var
}
return render(request, "post_list.html", context)
templates/post_detail.html
{%extends 'base.html' %}
{% block head %} {{instance.title}} {%endblock head %}
{% block content %}
<div class="col-sm-6 col-sm-offset-3">
{% if instance.image %}
<img src="{{instance.image.url}}" class="img-responsive"/>
{% endif %}
<h1>{{title}}<small>{{instance.timestamp}}</small></h1>
{{instance.content}}<br/>
</div>
{%endblock content %}
post_list.html
{% extends "base.html" %}
{%block content %}
<h1>{{title}} <small>{% if instance.draft %}<span style="color: 'red';">Draft{{instance.publish}}</span>{% endif %}</small></h1>
{% for obj in object_list %}
<div>
<!-- {% url 'posts:detail' id=obj.id %} -->
{{obj.title}}<br/>
{{obj.publish}}<br/>
{{obj.updated}}<br/>
{{obj.content|linebreaks|truncatechars:120}}<br/>
{% endfor %}
</div>
{% for contact in contacts %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}<br>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if object_list.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ object_list.number }} of {{ query_list.paginator.num_pages }}.
</span>
{% if object_list.has_next %}
next
last »
{% endif %}
</span>
</div>
{%endblock content %}
I am new to coding and especially new to working with Django. I want to build a small "forum" for me and the other students and it works pretty fine.
There is just one error I encounter over and over:
Exception Type: NoReverseMatch
Exception Value: Reverse for 'thread-create' with
arguments '('',)' not found. 1 pattern(s) tried: ['forum/(?P<pk>[0-9]+)/add/$']
I can work around it using functions instead of class based Views, but I doubt that's how it's supposed to be done.
I have the feeling I am missing something very important while working with class views.
I really would appreciate if someone could help me out :-)
It's the links that are not working:
{% url 'user-posts' thread.author.username %}
and more importantly:
{% url 'forum:thread-create' thread.id %}
What's also not working while using classes is:
{% for thread in thema.thread_set %} (works with the functions)
(I only want to see the threads that are bind to a certain thema. That also works pretty well with functions).
And you might also be asking why I don't just use the function based views:
I want to know what am I doing wrong
I want to be able to easy paginate my site.
Code:
# models.py
from django.db import models
from django.urls import reverse
from PIL import Image
from django.utils import timezone
from django.contrib.auth.models import User
class Thema(models.Model):
themengebiet = models.CharField(max_length=350)
beschreibung = models.TextField()
themen_logo = models.FileField(max_length=350, upload_to="logos", default='default.jpg')
erstellt_am = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.themengebiet
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.themen_logo.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.themen_logo.path)
class Thread(models.Model):
thema = models.ForeignKey(Thema, on_delete=models.CASCADE)
titel = models.CharField(max_length=350)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
erstellt_am = models.DateTimeField(default=timezone.now)
thread_logo = models.ImageField(upload_to="logos", d efault='default.jpg')
def get_absolute_url(self):
return reverse('forum:thread-page', kwargs={'pk': self.thema.id})
def __str__(self):
return self.titel
class Posting(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
titel = models.CharField(max_length=350)
erstellt_am = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
inhalt = models.TextField()
def __str__(self):
return self.titel
views.py
from django.views import generic
from django.views.generic import CreateView, UpdateView, DeleteView, ListView
from .models import Thema, Thread, Posting
from django.shortcuts import render, get_object_or_404
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.core.paginator import Paginator
class ThemenView(ListView):
template_name = 'forum/posts_original.html'
context_object_name = 'all_themen'
def get_queryset(self):
return Thema.objects.all()
class ThemaCreate(CreateView):
model = Thema
fields = ['themengebiet', 'beschreibung', 'themen_logo']
success_url = "/forum/"
class ThreadCreate(CreateView):
model = Thread
fields = ['thema', 'titel', 'erstellt_am']
success_url = reverse_lazy('forum:posts_original')
def get_object(self):
return Thread.objects.get(pk=self.kwargs['pk'])
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostCreate(CreateView):
model = Posting
fields = ['thread', 'titel', 'inhalt', 'erstellt_am']
success_url = "/forum/"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class ThreadView(ListView):
model = Thread
context_object_name = 'threads'
template_name = 'forum/thread.html'
success_url = reverse_lazy('forum:posts_original')
def get_object(self):
return Thread.objects.get(pk=self.kwargs['pk'])
class PostView(ListView):
model = Posting
context_object_name = 'posts'
template_name = 'forum/posts.html'
urls.py
from django.urls import path
from . import views
app_name = 'forum'
urlpatterns = [
# /forum/
path('', views.ThemenView.as_view(), name='posts_original'),
# forum/id/
path('<int:pk>/', views.ThreadView.as_view(), name='thread-page'),
# forum/thread/add
#path('<int:pk>/add/', views.thread_create, name='thread-create'),
# forum/id//id
path('thread/<int:pk>/', views.PostView.as_view(), name='post-page'),
path('add/', views.ThemaCreate.as_view(), name='thema-create'),
path('<int:pk>/add/', views.ThreadCreate.as_view(), name='thread-create'),
path('thread/<int:pk>/add/', views.PostCreate.as_view(), name='post-create'),
]
'''
def thread(request, pk):
try:
thema = get_object_or_404(Thema, pk=pk)
except Thema.DoesNotExist:
raise Http404("Thema existitiert nicht")
return render(request, 'forum/thread.html', {'thema': thema})
def post(request, pk):
try:
thread = get_object_or_404(Thread, pk=pk)
except Thread.DoesNotExist:
raise Http404("Thema existitiert nicht!")
return render(request, 'forum/posts.html', {'thread': thread})
'''
{% extends "blog/base.html" %}
{{ threads }}
{% block content %}
Zurück zur Themenübersicht
{% for thread in threads %}
<article class="media content-section">
<img class="rounded-circle article-img" src= "{{ thread.thread_logo.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' thread.author.username %}">{{ thread.author }}</a>
<small class="text-muted">{{ thread.erstellt_am|date:"d. F Y" }}</small>
</div>
<h2><a class="article-title" href=" {% url 'forum:post-page' thread.id %}">{{ thread.titel }}</a></h2>
<p class="article-content">Thema: {{ thread.thema }}</p>
</div>
</article>
{% endfor %}
<form action="{% url 'forum:thread-create' thread.id %}" method="post" enctype="multipart/form-data" style="display: inline;">
{% csrf_token %}
Thread hinzufügen
</form>
{% endif %}
{% endblock content %}