why posts are not shown in home page? - django

when I add a post in the admin panel, the posts are not shown on the home page of the app.
it only shows spaces of the post but couldn't show writeup of the post on the home page.
views.py
from django.shortcuts import render,HttpResponseRedirect
from django.contrib import messages
from django.http import HttpResponse
from .forms import SignUpForm, LoginForm
from django.contrib.auth import authenticate, login, logout
from .models import Post
# Create your views here.
# home
def home(request):
posts = Post.objects.all()
return render(request, 'blog/home.html',{'posts':posts})
home.html
{% extends 'blog/base.html' %}
{% load static %}
{% block content %}
<div class="col-sm-10">
<h3 class="text-white my-5">Home Page</h3>
{% for post in posts %}
<div class="jumbotron jumbotron-fluid jumbo-colour">
<div class="container">
<h1 class="display-4 font-weight-bold">{{posts.title}}</h1>
<p class="lead">{{posts.desc}}</p>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
models.py
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=150)
desc = models.TextField()

There is a typo in your code. It should be:
{% for post in posts %}
<div class="jumbotron jumbotron-fluid jumbo-colour">
<div class="container">
<h1 class="display-4 font-weight-bold">{{post.title}}</h1> // not posts.title
<p class="lead">{{post.desc}}</p> // not posts.desc
</div>
</div>
{% endfor %}

Related

Django- Template not found

I can't seem to get my delete, edit and add review functionality working. The errors come as soon as I try to navigate to the urls I have set up. When I try and add a new review using my link on the reviews page I get the below message:
TemplateDoesNotExist at /reviews/add
I don't understand why because I have linked the url above to the template, which I have created.
The issue I have with my edit/delete views is that the url it searches for when I click the button is just /edit/ or /delete/ rather than reviews/edit/int:pk or reviews/delete/int:pk as per my urls.
I have pasted my code below, any help would be much appreciated! I have the feeling I am going to kick myself when I realise!
reviews.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid home-container">
<div class="row align-items-center">
<div class="col-sm-12 text-center mt-4">
<h2><strong>Reviews</strong></h2>
</div>
</div>
{% for review in reviews %}
<hr class="hr-1">
<div class="row featurette">
<div class="col-sm-12">
<h2 class="featurette-heading">{{ review.title }}</h2>
<p class="lead">{{ review.content }}</p>
<div class="row justify-content-between mx-1">
<p>By: {{ review.user }}</p>
<p>Created on: {{ review.created }}</p>
<p>Last Updated: {{ review.updated }}</p>
</div>
<!-- Add user authentication if -->
<div class="text-center">
<a href="edit/{{ review.id }}" class="mx-2">
<button class="positive-button mb-2">Edit</button></a>
<a href="delete/{{ review.id }}" class="mx-2 mb-2">
<button class="negative-button">Delete</button></a>
</div>
</div>
</div>
{% endfor %}
<div class="row">
<div class="col-sm-12 text-center py-4">
{% if user.is_authenticated %}
<a href="{% url 'home:add_review' %}">
<button class="positive-button-lg">Add a review</button>
</a>
{% else %}
<p>If you would like to add your own review, please login or sign up if you haven't already!</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
add_review.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<form method="post" style="margin-top: 1.3em;">
{{ review_form }}
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
</form>
</div>
</div>
{% endblock %}
views.py:
from django.shortcuts import render
from django.views import View
from django.urls import reverse_lazy
from django.views.generic import UpdateView, DeleteView
from .models import Reviews
from .forms import ReviewForm
def home(request):
''' Returns the home page.'''
return render(request, 'home/index.html')
def reviews(request):
''' Returns the reviews page.'''
serialized_reviews = []
reviews = Reviews.objects.all()
for review in reviews:
serialized_reviews.append({
"title": review.title,
"content": review.content,
"user": review.user,
"created": review.created,
"updated": review.updated,
})
context = {
"reviews": serialized_reviews
}
print(serialized_reviews)
return render(request, 'home/reviews.html', context)
class AddReview(View):
'''View which allows the user to add a new review.'''
def get(self, request, *args, **kwargs):
review = Reviews
review_form = ReviewForm
context = {
'review': review,
'review_form': review_form,
'user': review.user,
'title': review.title,
'content': review.content,
}
return render(request, 'add_review.html', context)
def post(self, request, *args, **kwargs):
review_form = ReviewForm(data=request.POST)
if review_form.is_valid():
obj = review_form.save(commit=False)
obj.user = request.user
obj.save()
return redirect("home:reviews")
class DeleteReview(DeleteView):
'''View which allows the user to delete the selected review.'''
model = Reviews
template_name = 'delete_review.html'
success_url = reverse_lazy('reviews')
class EditReview(UpdateView):
'''View which allows the user to edit the selected review.'''
model = Reviews
template_name = 'edit_review.html'
fields = ['title', 'content']
urls.py:
from django.urls import path
from . import views
app_name = 'home'
urlpatterns = [
path('', views.home, name='home'),
path('reviews', views.reviews, name='reviews'),
path('reviews/add', views.AddReview.as_view(), name='add_review'),
path('reviews/delete/<int:pk>', views.DeleteReview.as_view(), name='delete_review'),
path('reviews/edit/<int:pk>', views.EditReview.as_view(), name='edit_review'),
]
The main difference is my app name, which is 'core'. Also, I forgot to add the content field to the model, but that is easily done, the form will just handle it as soon as you do the migration. (except on list.html)
models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
class Reviews(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
title = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=timezone.now())
updated_at = models.DateTimeField(auto_now=timezone.now())
forms.py
from django import forms
from core.models import Reviews
class ReviewsForm(forms.ModelForm):
class Meta:
model = Reviews
fields = '__all__'
views.py
from core.models import Reviews
from core.forms import ReviewsForm
from django.shortcuts import render, redirect
def list_reviews(request):
reviews = Reviews.objects.all()
context = {
"reviews": reviews
}
return render(request, 'reviews/list.html', context)
def add_review(request):
if request.method == 'POST':
form = ReviewsForm(request.POST)
if form.is_valid():
form.save()
return redirect('/reviews/')
else:
form = ReviewsForm()
context = {
'form': form
}
return render(request, 'reviews/detail.html', context)
def edit_review(request, pk):
if request.method == 'POST':
form = ReviewsForm(request.POST)
if form.is_valid():
obj = Reviews.objects.get(id=pk)
obj.title = form.cleaned_data['title']
obj.user = form.cleaned_data['user']
obj.save()
return redirect('/reviews/')
else:
obj = Reviews.objects.get(id=pk)
form = ReviewsForm(instance=obj)
context = {
'form': form
}
return render(request, 'reviews/detail.html', context)
def delete_review(request, pk):
obj = Reviews.objects.get(id=pk)
obj.delete()
return redirect('/reviews/')
urls.py
from django.urls import path
import core.views as views
app_name = 'core'
urlpatterns = [
path('reviews/', views.list_reviews, name='list-reviews'),
path('reviews/add', views.add_review, name='add-review'),
path('reviews/edit/<int:pk>/', views.edit_review, name='edit-review'),
path('reviews/delete/<int:pk>/', views.delete_review, name='delete-review'),
]
list.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid home-container">
<div class="row align-items-center">
<div class="col-sm-12 text-center mt-4">
<h2><strong>Reviews</strong></h2>
</div>
</div>
{% for review in reviews %}
<hr class="hr-1">
<div class="row featurette">
<div class="col-sm-12">
<h2 class="featurette-heading">{{ review.title }}</h2>
<p class="lead">{{ review.content }}</p>
<div class="row justify-content-between mx-1">
<p>By: {{ review.user }}</p>
<p>Created on: {{ review.created_at }}</p>
<p>Last Updated: {{ review.updated_at }}</p>
</div>
<!-- Add user authentication if -->
<div class="text-center">
<a href="{% url 'core:edit-review' pk=review.id %}" class="mx-2">
<button class="positive-button mb-2">Edit</button></a>
<a href="{% url 'core:delete-review' pk=review.id %}" class="mx-2 mb-2">
<button class="negative-button">Delete</button></a>
</div>
</div>
</div>
{% endfor %}
<div class="row">
<div class="col-sm-12 text-center py-4">
{% if user.is_authenticated %}
<a href="{% url 'core:add-review' %}">
<button class="positive-button-lg">Add a review</button>
</a>
{% else %}
<p>If you would like to add your own review, please login or sign up if you haven't already!</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
detail.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<form method="post" style="margin-top: 1.3em;">
{% csrf_token %}
<table>
{{ form }}
</table>
<button type="submit" class="btn btn-primary btn-lg">Save</button>
</form>
</div>
</div>
{% endblock %}
According to your urls, It is a review/edit/<int:pk>.
So you must add same thing in href tag.
Change this:
<a href="edit/{{ review.id }}"
To this:
<a href="review/edit/{{ review.id }}"
That's why you are getting that error
I've fixed it, firstly the path in my add_review view was wrong, which I have amended and it now works (thanks Ivan).
I also was not actually bringing the ID through on my 'reviews' view in the first place, so when following the links on my edit and review buttons, it didn't know what I meant by 'id', as I hadn't specified what that was in the view context.
Thanks for the help all!
I think you're writing in your urls the wrong way, like this below your div text-center:
<a href="edit/{{ review.id }}" class="mx-2">
It should be:
<a href="{% url 'yourappname:edit' review.id %}">

Django Model objects not displaying in my template

I am new to Django. I have problem in displaying model objects into my template
here is my models.py:
from django.db import models
from django.contrib.auth.models import User
class Employee(models.Model):
username = models.TextField(max_length=100)
email = models.CharField(max_length=100)
password = models.TextField(max_length=100)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.username
here is my views.py:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Employee
#login_required
def home(request):
context ={
'employee': Employee.objects.all()
}
return render(request, 'newusers/home.html', context)
here is my template code:
{% extends "users/base.html" %} {% load crispy_forms_tags %} {% block content %}
<article class="media content-section">
<div class="media-body">
<div class="card">
<a class="mr-2" href="#">{{ employee.username }}</a>
<small class="text-muted">{{ employee.email }}</small>
</div>
</div>
</article>
{% endblock content %}
You get two distinct notions mixed up: querysets and model instances.
Employee.objects.all(), that is to say currently employee in your template, is a queryset.
Depending on what you exactly want to achieve, you need to iterate this queryset to access each instance attributes:
# views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Employee
#login_required
def home(request):
context ={'employees': Employee.objects.all()} # note the s at the end
# here you may want to print `list(context["employees"])` to understand the queryset structure
return render(request, 'newusers/home.html', context)
And then for each employee of the queryset employees:
{% block content %}
{% for employee in employees %}
<article class="media content-section">
<div class="media-body">
<div class="card">
<a class="mr-2" href="#">{{ employee.username }}</a>
<small class="text-muted">{{ employee.email }}</small>
</div>
</div>
</article>
{% endfor %}
{% endblock %}

Why I can not display two listviews in one template?

I am working on a Django project where admin can upload a hero banner to the site and can also upload a notification on the home page of the site.
So I made listviews for listing the two HeroListView and NotificationListView for that.
But the second one is not appearing in the page.
Please tell me how to solve this issue.
This is the models.py file
from django.db import models
class Hero(models.Model):
image = models.ImageField(upload_to="heros/")
class Notification(models.Model):
notification = models.CharField(max_length=200)
This is the views.py file.
from django.views.generic import ListView
from .models import Hero, Notification
class HeroListView(ListView):
model = Hero
template_name = "home.html"
context_object_name = "hero_list"
class NoticficationListView(ListView):
model = Notification
template_name = "home.html"
context_object_name = "notification_list"
this is the app/urls.py file
from django.urls import path
from .views import HeroListView, NoticficationListView
urlpatterns = [
path("", HeroListView.as_view(), name="home"),
path("", NoticficationListView.as_view(), name="home"),
]
this is the project/urls.py file
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path("", include("heros.urls")),
path("", include("products.urls")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
{% extends '_base.html' %}
{% block title %}Home{% endblock title %}
{% block content %}
{% load static %}
<div class="container mt-4">
<div id="carouselExampleControls" class="carousel carousel-dark slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="{% static 'images/hero2.jpg' %}" class="d-block w-100" alt="..." style="max-height: 400px;">
</div>
{% for hero in hero_list %}
<div class="carousel-item">
<img src="{{ hero.image.url }}" class="d-block w-100" alt="..." style="max-height: 400px;">
</div>
{% endfor %}
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<div class="div">
{% for note in notification.list %}
<p>{{ note.notification }}</p>
{% endfor %}
</div>
</div>
{% endblock content %}
please tell me how to solve this issue.
You can do it this way
class HeroListView(ListView):
model = Hero
template_name = "home.html"
def get_context_data(self):
context = super(HeroListView, self).get_context_data()
context['hero_list'] = Hero.objects.all()
context['notification_list'] = Notification.objects.all()
return context
You can't access two or multiple views at the same time, so in your case, you can remove NoticficationListView and use only HeroListView to render both hero_list and notification_list

Page not found (404) Request Method:

please help me. I don't know why can't see the detail of product when i click a product. both first list work good just when i need to see detail of product in second list(filtered list) an 404 error shows.
thanks
here is my code below:
my urls:
from django.urls import path
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.HomeView.as_view(), name='home'),
path('categories/<category>/', views.ProductListView.as_view(), name='product-list'),
path('categories/<int:pk>/', views.ProductDetailView.as_view(), name='product-detail'),
]
views:
from django.shortcuts import render, get_object_or_404, get_list_or_404
from django.views import generic
from .models import Category, Product
class HomeView(generic.ListView):
model = Category
template_name = 'home.html'
class ProductListView(generic.ListView):
template_name = 'product_list.html'
def get_queryset(self):
self.category = get_object_or_404(Category, title=self.kwargs['category'])
return Product.objects.filter(category=self.category)
class ProductDetailView(generic.DetailView):
model = Product
template_name = 'product_detail.html'
product_list.html
{% extends 'base.html' %}
{% load static %}
{% block title %}
Welcome | Global Market
{% endblock %}
{% block content %}
{% for product in product_list %}
<a href="{% url 'shop:product-detail' product.pk %}">
<div class="card bg-light mb-3" style="max-width: 18rem;">
<div class="card-header">{{ product.title }}</div>
<img class="card-img-top" src="{{ product.image.url }}" alt="{{ product.title }}">
<div class="card-body">
<p class="card-text">{{ product.description }}</p>
</div>
</div>
</a>
{% endfor %}
{% endblock %}
product_detail.html
{% extends 'base.html' %}
{% load static %}
{% block title %}
Welcome | Global Market
{% endblock %}
{% block content %}
<h1>thid</h1>
{{ product.name }}
{% endblock %}
Even if the you visit /categories/1, it will use the ProductListView, since the str path converter also accepts a sequence of digits. You can swap the paths, so:
from django.urls import path
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.HomeView.as_view(), name='home'),
path('categories/<int:pk>/', views.ProductDetailView.as_view(), name='product-detail'),
path('categories/<category>/', views.ProductListView.as_view(), name='product-list'),
]
Then for /categories/1, it will match with <int:pk> as 1, and thus fire the ProductDetailView.

I want to use paginator by using class based view on django

As I mentioned at Title I want to use paginator.
I coded as Django Docs introduced but it's not work.
What is the reason??
This is my View
from django.shortcuts import render_to_response
from django.views.generic import CreateView, ListView, UpdateView, DetailView
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Article
class ArticleListView(ListView):
model = Article
def listing(request):
article_list = Article.objects.all()
paginator = Paginator(article_list, 7)
page = request.GET.get('page')
try:
articles = paginator.page(page)
except PageNotAnInteger:
articles = paginator.page(1)
except EmptyPage:
articles = paginator.page(paginator.num_pages)
return render_to_response('blog/article_list.html', {'articles': articles})
and the following is my urls
from django.conf.urls import patterns, url
from .views import ArticleCreateView, ArticleUpdateView, ArticleListView, ArticleDetailView
urlpatterns = patterns('',
url(r'^list/$', ArticleListView.as_view(), name='list'),
)
the last is my template
{% extends 'base.html' %}
{% block title %} list {% endblock %}
{% block content %}
<p>
new
</p>
{% for article in article_list %}
<div id="article">
<div id="author">
<p>{{ article.author }}</p>
</div>
<div id="time">
<p>{{ article.created }}</p>
</div>
<div id="body">
<p>{{ article.body }}</p>
</div>
<div id="edit">
modify
</div>
</div>
{% endfor %}
{% for article in articles %}
{{ article.full_name|upper }}<br>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if articles.has_previous %}
pre
{% endif %}
<span class="current">
Page {{ articles.number }} of {{ articles.paginator.num_pages }}
</span>
{% if articles.has_next %}
next
{% endif %}
</span>
</div>
{% endblock %}
what is problem??
I think server cannot dectect def listing in class based view