I want to create app with search and pagination. Pagination didn't work with ListView.
When I click on the link "next" I am moving from start page http://127.0.0.1:8001/ ---> to the http://127.0.0.1:8001/?city=2 but elements of the list did not change.
And next click to the "next" link did not changes the url ( http://127.0.0.1:8001/?city=2 --> http://127.0.0.1:8001/?city=2).
Could you help me to find error?
I think that error in *.html file, but can't find it
My code:
models.py
from django.db import models
class City(models.Model):
name = models.CharField(max_length=255)
state = models.CharField(max_length=255)
class Meta:
verbose_name_plural = "cities"
def __str__(self):
return self.name
urls.py
# cities/urls.py
from django.urls import path
from . import views
from .views import HomePageView, SearchResultsView
urlpatterns = [
path('search/', SearchResultsView.as_view(), name='search_results'),
path('', HomePageView.as_view(), name='home'),
path('city/<int:pk>/', views.city_detail, name='city_detail'),
]
views.py
from django.shortcuts import render
from django.views.generic import TemplateView, ListView
from .models import City
from django.db.models import Q
from django.shortcuts import render, get_object_or_404
class HomePageView(ListView):
model = City
template_name = 'cities/home.html'
paginate_by = 3
def city_detail(request, pk):
city = get_object_or_404(City, pk=pk)
return render(request, 'cities/city_detail.html', {'city': city})
class SearchResultsView(ListView):
model = City
template_name = 'cities/search_results.html'
def get_queryset(self): # new
query = self.request.GET.get('q')
object_list = City.objects.filter(
Q(name__icontains=query) | Q(state__icontains=query)
)
return object_list
home.html
<!-- templates/home.html -->
<h1>HomePage</h1>
<form action="{% url 'search_results' %}" method="get">
<input name="q" type="text" placeholder="Search...">
</form>
<ul>
{% for city in object_list %}
<li>
<h1>{{ city.name }}</h1>
</li>
{% endfor %}
</ul>
{{page_obj}}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
previous
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
{% endif %}
</span>
</div>
The standard name for the page query parameter is 'page' You should either change the name of the queryparameter, or render the template with the ?page= parameter.
Option 1: Changing the page_kwarg
You can change that by altering the page_kwarg attribute [Django-doc]:
class HomePageView(ListView):
model = City
template_name = 'cities/home.html'
paginate_by = 3
page_kwarg = 'city'
Option 2: Changing the template
It might be more sensical however to simply change the template, such that it uses page as parameter:
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
previous
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
{% endif %}
</span>
</div>
Related
my views.py file:
from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import (
LoginRequiredMixin,
UserPassesTestMixin,
)
from .models import Post
# Create your views here.
class PostListView(ListView):
model = Post
template_name = "blog/index.html"
context_object_name = "posts"
ordering = ["-date_posted"]
class PostDetailView(DetailView):
model = Post
class PostCreateView(CreateView, LoginRequiredMixin, UserPassesTestMixin):
model = Post
fields = ['title', 'genere', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostUpdateView(UpdateView, LoginRequiredMixin, UserPassesTestMixin):
model = Post
success_url = "blog-home"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
class PostDeleteView(DeleteView, LoginRequiredMixin, UserPassesTestMixin):
model = Post
success_url = "/"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def about(request):
return render(request, 'blog/about.html')
My models.py:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
genere = models.CharField(max_length=50, default='')
def __str__(self):
return f'{self.title} by {self.author}'
def get_absolute_url(self):
return reverse('blog-home')
my urls.py url:
from django.urls import path
from .views import PostListView, PostDetailView, PostCreateView, PostUpdateView, PostDeleteView
from . import views
urlpatterns = [
path("", PostListView.as_view(), name="blog-home"),
path("about", views.about, name="blog-about"),
path("post/<int:pk>", PostDetailView.as_view(), name="blog-detail"),
path("post/new", PostCreateView.as_view(), name="blog-create"),
path("post/<int:pk>/update", PostUpdateView.as_view(), name="blog-update"),
path("post/<int:pk>/delete", PostDeleteView.as_view(), name="blog-delete"),
]
index.html
{% extends "blog/base.html" %}
{% load static %}
{% block content %}
<div class="row tm-row">
{% for post in posts %}
<article class="col-12 col-md-6 tm-post">
<hr class="tm-hr-primary">
<a href="{% url 'blog-detail' post.id %}" class="effect-lily tm-post-link tm-pt-60">
<div class="tm-post-link-inner">
<img src="{% static 'img/img-01.jpg' %}" alt="Image" class="img-fluid">
</div>
<span class="position-absolute tm-new-badge">New</span>
<h2 class="tm-pt-30 tm-color-primary tm-post-title">{{ post.title }}</h2>
</a>
<p class="tm-pt-30">
{{ post.content|safe|truncatewords:"30"|linebreaks }}
</p>
<div class="d-flex justify-content-between tm-pt-45">
<span class="tm-color-primary">{{ post.genere }}</span>
<span class="tm-color-primary">{{ post.date_posted|date:'N j,Y' }}</span>
</div>
<hr>
<div class="d-flex justify-content-between">
<span>36 comments</span>
<span>by {{ post.author }}</span>
</div>
</article>
{% endfor %}
</div>
{% endblock %}
post_detail.html:
{% extends 'blog/base.html' %}
{% load crispy_forms_tags %}
{% load static %}
{% block content %}
<div class="container">
<article class="col-12 col-md-6 tm-post">
<hr class="tm-hr-primary">
<a href="" class="effect-lily tm-post-link tm-pt-60">
<div class="tm-post-link-inner">
<img src="{% static 'img/img-01.jpg' %}" alt="Image" class="img-fluid">
</div>
<span class="position-absolute tm-new-badge">New</span>
<h2 class="tm-pt-30 tm-color-primary tm-post-title">{{ object.title }}</h2>
{% if object.author == user %}
<a class="btn btn-outline-danger" href="{% url 'blog-delete' object.id %}">Delete</a>
<a class="btn btn-outline-secondary" href="{% url 'blog-update' object.id %}">Update</a>
{% endif %}
</a>
<p class="tm-pt-30">
{{ object.content }}
</p>
<div class="d-flex justify-content-between tm-pt-45">
<span class="tm-color-primary">{{ object.genere }}</span>
<span class="tm-color-primary">{{ object.date_posted|date:'N j,Y' }}</span>
</div>
<hr>
<div class="d-flex justify-content-between">
<span>36 comments</span>
<span>by {{ object.author }}</span>
</div>
</article>
</div>
{% endblock %}
post_confirm_delete.html:
{% extends 'blog/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<form method="POST">
{% csrf_token %}
<h2>Are You Sure You Want To Delete "{{ object.title }}"</h2>
<button class="btn btn-outline-danger">Yes, I'm Sure</button>
<a class="btn btn-outline-secondary" href="{% url 'blog-detail' object.id %}">Cancel</a>
</form>
</div>
{% endblock %}
So, what I'm getting is that suppose 2 person jeff and ram are users so ram cannot update the posts of jeff and vice versa.
And if jeff views the post of ram, so he does not get the update and delete, so he cannot edit the post of ram but if jeff goes to "127.0.0.1:8000/post/9/delete" from "127.0.0.1:800/post/9",
So he get the confirm delete page and he can even delete his post.
How can I fix this bug in my project??????
you can use get_queryset() to restrict query in database
class PostUpdateView(UpdateView, LoginRequiredMixin, UserPassesTestMixin):
model = Post
success_url = "blog-home"
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def get_queryset(self):
pk = self.kwargs.get(self.pk_url_kwarg)
return self.model.objects.filter(pk=pk,user=self.request.user)
Added the ability to add comments, made it so that only authorized users can add comments, but for some reason this does not work, please fix it.
I also added tag strong, but for some reason it does not work either
post_detail.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<link href="{% static 'css/post_detail.css' %}" rel="stylesheet">
<div class="post-entry">
<h2>{{ post.title }}</h2>
<p>{{ post.body|urlize }}</p>
</div>
<p>+ Edit Blog Post</p>
<p>+ Delete Blog Post</p>
{% if post.header_image %}
<p><img src="{{post.header_image.url}}"></p>
{% else %}
<p></p>
{% endif %}
{% for comm in post.commentpost_set.all%}
{{ comm.user }} <br>
{{ comm.text }} <br><br>
{% endfor %}
<br>
<hr>
<h2>Comments...</h2>
{% if not post.comments.all %}
No Comments Yet...<a href="{% url 'post_comment' post.pk %}">
Add Comment</a>
{% else %}
<form method="post">
{% csrf_token %}
{{ comment_form.as_p }}
{% if request.user.is_authenticated %}
Add Comment<br><br>
{% else %}
Add Comment<br><br disabled>
{% endif %}
</form>
{% for comment in post.comments.all %}
<strong>
{{ comment.name }} -
{{ comment.date_added }}
</strong>
<br>
{{ comment.body }}
<br><br>
{% endfor %}
{% endif %}
{% endblock content %}
views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy, reverse
from .models import Post, Comment
from .forms import CommentForm
from django.http import HttpResponseRedirect
class BlogListView(ListView):
model = Post
template_name = 'home.html'
context_object_name = 'posts'
paginate_by = 2
queryset = Post.objects.all()
class BlogDetailView(DetailView):
model = Post
template_name = 'post_detail.html'
class BlogCreateView(CreateView):
model = Post
template_name = 'post_new.html'
fields = ['title', 'author', 'body', 'header_image']
class BlogCommentView(CreateView):
model = Comment
form_class = CommentForm
template_name = 'post_comment.html'
def form_valid(self, form):
form.instance.post_id = self.kwargs['pk']
return super().form_valid(form)
success_url = reverse_lazy('home')
#fields = '__all__'
class BlogUpdateView(UpdateView):
model = Post
template_name = 'post_edit.html'
fields = ['title', 'body', 'header_image']
class BlogDeleteView(DeleteView):
model = Post
template_name = 'post_delete.html'
success_url = reverse_lazy('home')
#property
def image_url(self):
if self.image:
return getattr(self.photo, 'url', None)
return None
Write what files still need to be shown, I will show
Thanks everyone!
<form method="post">
{% csrf_token %}
{{ comment_form.as_p }}
{% if request.user.is_authenticated %}
Add Comment<br><br>
{% else %}
Add Comment<br><br>
{% endif %}
</form>
I have been working on to make the website which people can post their review on restaurants. I finished creating urls.py, views.py, models.py and html file.
I tried to connect the list page with the detailed page on each restaurants. Therefore, I used str:pk tag to connect list page with detail page.
However it does't work and however times I check, I can't find why the error happens.
settings and other settings are already done. I only have to adjust app files.
My Goal:
List of restaurants are already created. I want user to be able to go to the detail page by clicking the button below the "{{ list.outline}}"
models.py
from django.db import models
from django.utils import timezone
stars = [
(1,"☆"),
(2,"☆☆"),
(3,"☆☆☆"),
(4,"☆☆☆☆"),
(5,"☆☆☆☆☆")
]
# Create your models here.
class Tabelog(models.Model):
store_name = models.CharField("店名",max_length = 124,primary_key=True)
title = models.CharField("タイトル",max_length = 124,null=True,blank=True)
evaluation = models.IntegerField("評価",choices = stars)
comment = models.TextField("口コミ")
create_date = models.DateField("口コミ投稿日",default=timezone.now)
price = models.PositiveIntegerField("値段",help_text='円',default=0)
def outline(self):
return self.comment[:10]
def __str__(self):
return ("{},{},{}".format(self.store_name,self.evaluation,self.comment[:10]))
urls.py
from django.urls import path,include
from Tabelog import views
from Tabelog.views import ReviewList,ReviewDetail,ReviewForm,ReviewFix,ReviewDelete,ReviewContact,ReviewContactComplete
app_name = "Tabelog"
urlpatterns = [
path("lp/", views.lp,name="lp"),
path("list/", ReviewList.as_view(),name="list"),
path("detail/<str:pk>/",ReviewDetail.as_view(),name="detail"),
path("form/",ReviewForm.as_view(),name="form"),
path("form/fix/<str:pk>/",ReviewFix.as_view(),name="form_fix"),
path("form/delete/<str:pk>/",ReviewDelete.as_view(),name="delete"),
path("contact/",ReviewContact.as_view(),name="contact"),
path("contact/complete/",ReviewContactComplete.as_view(),name="ContactComplete")
]
forms.py
from django.shortcuts import render,redirect,get_object_or_404
from Tabelog.models import Tabelog
from Tabelog.forms import CreateTabelogForm
from django.views import generic
from Tabelog.forms import CreateTabelogForm,ContactForm
from django.urls import reverse_lazy
from django.core.mail import send_mail
from django.template.loader import render_to_string
# Create your views here.
def lp(request):
return render(request,"Tabelog/lp.html")
class ReviewList(generic.ListView):
model = Tabelog
class ReviewDetail(generic.DetailView):
model = Tabelog
class ReviewForm(generic.CreateView):
model = Tabelog
form_class = CreateTabelogForm
success_url = reverse_lazy("Tabelog:list")
class ReviewFix(generic.UpdateView):
model = Tabelog
fields = "__all__"
success_url = reverse_lazy("Tabelog:list")
class ReviewDelete(generic.DeleteView):
model = Tabelog
success_url = reverse_lazy("Tabelog:list")
class ReviewContact(generic.FormView):
template_name = "Tabelog/tabelog_contact.html"
form_class = ContactForm
success_url = reverse_lazy("Tabelog:ContactComplete")
def form_valid(self,form):
subject = "お問い合わせがありました"
message = render_to_string('Tabelog/mail.txt',form.cleaned_data,self.request)
from_email = "toiawase#gmail.com"
recipient_list = ["yutotennisnowboard#gmail.com"]
send_mail(subject,message,from_email,recipient_list)
return redirect('Tabelog:list')
class ReviewContactComplete(generic.TemplateView):
template_name = "Tabelog/tabelog_contact_complete.html"
tabelog_list.html
<!DOCTYPE html>
{% extends 'diary/base.html' %}
{% block title %}お店リスト{% endblock %}
{% block content %}
{% for list in object_list %}
<div class="card border-primary mb-3">
<div class="card-body text-primary">
<h1 class="card-title">{{list.store_name}}</h1>
<h2 class="card-text">{{ list.get_evaluation_display}}</h2>
<span class="card-text">{{ list.outline}}</span><br>
<button type="button" class="btn btn-light"> See More Detail! </button>
</div>
</div>
{% endfor %}
{% endblock %}
tabelog_detail.html
<!DOCTYPE html>
{% extends 'diary/base.html' %}
{% load static %}
{% block title %}Detail Page{% endblock %}
{% block design %}
<link rel="stylesheet" href="{% static 'css/detail.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<div class="card border-info mb-3">
<div class="card-body">
<h1 class="card-title">{{object.title}}</h1>
<p class="card-text">投稿者:{{ object.writer }}</p>
<p class="card-text">作成日:{{ object.created_at}}</p>
<p class="card-text">更新日:{{ object.last_modefied}}</p>
<p class="card-text">カテゴリ:{{ object.category}}</p>
<p class="card-text">タグ:{% for tag in object.tag.all %}{{tag}},{% endfor %}</p>
<div class="card-text">
{{object.text| linebreaks | urlize }}
</div><br>
<button type="button" class="btn btn-light"> Change the post </button>
</div>
</div>
</div>
<div class="container">
<button type="button" class="btn btn-light"> コメントする</button>
</div>
<div class="container">
<article class="card border-info mb-3" id="comment">
<div class="card-body">
{% for comment in article.comment_set.all %}
<p class="card-text">{{comment | linebreaks | urlize}}</p>
{% endfor %}
</div>
</article>
</div>
{% endblock %}
The problem was caused by the detail page connected from list page. I realized that the error message doesn't necessarily show the specific cause.
Please, click the link to see the picture to see the error.
base.html
<ul class= 'nav navbar-nav navbar-right'>
{% if user.is_authenticated %}
<li>
New post
</li>
<li>
Drafts
</li>
<li>
Log out
</li>
<li>
<a >Welcome: {{ user.username }}</a>
</li>
{% else %}
<li>
<a class = 'nav navbar-right' href="{% url 'login' %}">
<span class = 'glyphicon glyphicon-user'></span>
</a>
<a class = 'nav navbar-right' href= "{% url 'signup' %}">
Sign up</a>
post_detail.html
{% extends 'blog/base.html'%}
{% block content %}
<h1 class= 'posttitle loader'>{{ post.title }}</h1>
{% if post.published_date %}
<div class="date postdate">
{{ post.published_date }}
</div>
{% else %}
<a class = 'btn btn-primary' href=" {% url 'post_publish' pk=post.pk
%}">Publish</a>
{% endif %}
<p class = 'postcontent'> {{ post.text|safe|linebreaksbr}}</p>
{% if user.is_authenticated %}
<a class= 'btn btn-primary' href="{% url 'post_edit' pk=post.pk %}">
<span class = 'glyphicon glyphicon-pencil'></span>
</a>
<a class= 'btn btn-primary' href="{% url 'post_remove' pk=post.pk %}">
<span class = 'glyphicon glyphicon-remove'></span>
</a>
{% endif %}
<hr>
{% if user.is_authenticated %}
<a class = 'btn btn-primary btn-comment' href="{% url 'add_comment_to_post'
pk=post.pk %}">Comment</a>
{% else %}
<a class = 'btn btn-primary btn-comment' href="{% url 'comment_redirect'
pk=post.pk %}">Comment</a>
{% endif %}
<div class="container">
{% for comment in post.comments.all %}
<br>
{% if user.is_authenticated or comments.approved_comments %}
{{ comment.created_date }}
{% if not comment.approved_comments %}
<a class= 'btn btn-default' href="{% url 'comment_remove' pk=comment.pk
%}">
<span class = 'glyphicon glyphicon-remove'></span></a>
<a class= 'btn btn-primary' href="{% url 'comment_approve' pk=comment.pk
%}">
<span class = 'glyphicon glyphicon-ok'></span></a>
{% else %}
{% endif %}
<p>{{ comment.text|safe|linebreaks }}</p>
<p>Posted by: {{ comment.author }}</p>
{% endif %}
{% empty %}
<p>No comments</p>
{% endfor %}
</div>
{% endblock %}
post_form.html
% extends 'blog/base.html'%}
{% load bootstrap3 %}
{% block content %}
<h1>New post</h1>
<form class="post-form" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
<script>
var editor = new MediumEditor('.editable');
</script>
{% endblock %}
urls.py
from django.conf.urls import url
from blog import views
urlpatterns = [
url(r'^about/$', views.AboutView.as_view(), name = 'about'),
url(r'^$', views.PostListView.as_view(),name = 'post_list' ),
url(r'^post/(?P<pk>\d+)$', views.PostDetailView.as_view(), name = 'post_detail'),
url(r'^post/new/$', views.CreatePostView.as_view(), name = 'post_new'),
url(r'^post/(?P<pk>\d+)/edit/$', views.PostUpdateView.as_view(), name = 'post_edit'),
url(r'^post/(?P<pk>\d+)/remove/$', views.PostDeleteView.as_view(), name = 'post_remove'),
url(r'^drafts/$', views.DraftListView.as_view(),name = 'post_draft_list' ),
url(r'^post/(?P<pk>\d+)/Comment/$', views.add_comment_to_post, name = 'add_comment_to_post'),
url(r'^comment/(?P<pk>\d+)/approve/$',views.comment_approve, name = 'comment_approve'),
url(r'^comment/(?P<pk>\d+)/remove/$',views.comment_remove, name = 'comment_remove'),
url(r'^signup/$', views.SignUp.as_view(), name ='signup'),
url(r'^comment/(?P<pk>\d+)/Comment/$', views.comment_red, name = 'comment_redirect'),
url(r'^post/(?P<pk>\d+)/publish/$', views.post_publish,
name='post_publish'),
]
views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from django.views.generic import (TemplateView, ListView, DetailView,
CreateView,UpdateView,DeleteView)
from blog.models import Post,comments, User
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserCreationForm
from blog.forms import PostForm, CommentsForm
from django.urls import reverse_lazy
from django.contrib.auth import login, logout
from . import forms
Created views here.
class AboutView(TemplateView):
template_name = 'about.html'
class PostListView(ListView):
model = Post
def get_query(self):
return post.object.filter(published_date__lte=timezone.now()).orderby('-
published_date')
class PostDetailView(DetailView):
model = Post
class CreatePostView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'blog/post_detail.html'
form_class = PostForm
model = Post
class PostUpdateView(LoginRequiredMixin, UpdateView):
login_url = '/login/'
redirect_field_name = 'blog/post_detail.html'
form_class = PostForm
model = Post
class PostDeleteView(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('post_list')
class DraftListView(LoginRequiredMixin, ListView):
login_url = '/login/'
redirect_field_name = 'blog/post_draft_list.html'
model = Post
def get_query(self):
return post.object.filter(published_date__isnull =
True).order_by('created_date')
class SignUp(CreateView):
form_class = forms.UserCreateForm
success_url = reverse_lazy('login')
template_name = 'sign_up.html'
model = User
############COMMENT###################
#login_required
def post_publish(request, pk):
post = get_object_or_404(Post, pk=pk)
post.publish()
redirect('post_detail', pk=pk)
def comment_red(request,pk):
post = get_object_or_404(Post, pk=pk)
return render(request,'blog/comment_redirect.html')
#login_required
def add_comment_to_post(request,pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = CommentsForm(request.POST)
if form.is_valid():
comment = form.save(commit = False)
comment.post = post
comment.save()
return redirect('post_detail', pk=post.pk)
else:
form = CommentsForm()
return render(request, 'blog/comment_form.html',{'form':form})
#login_required
def comment_approve(request, pk):
comment = get_object_or_404(comments, pk=pk)
comment.approve()
return redirect('post_detail', pk=comment.post.pk)
#login_required
def comment_remove(request, pk):
comment = get_object_or_404(comments, pk=pk)
comment.delete()
return redirect('post_detail', pk=comment.post.pk)
Can I anyone please help me where I got wrong or what I need to, I just got stuck on this. Initially, it was working fine when I click New post on nav bar, it would lead me to the form when I can input text and author but now when I click there, I get this NoReverseMatch at /post/new/ Reverse for 'post_publish' with keyword arguments '{'pk': ''}' not found.
Thank you.
My first guess is that post object is null here:
<a class = 'btn btn-primary' href=" {% url 'post_publish' pk=post.pk
%}">Publish</a>
But to be sure we need a full stack strace.
EDIT #1
We are still missing the traceback, i cannot see it in your picture, but my answer is still valid. post.pk is None, you should replace it with object.pk since you're using a Detailview.
https://docs.djangoproject.com/en/2.0/ref/class-based-views/generic-display/#detailview
I have a lots of apps, but I want to generate all app's data on my homepage. Here's my apps:blog,members
I want to show blogs and my members on my homepage
I know that if I want to generate one app's data,I can do this:
blog/urls.py:
urlpatterns = [
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:10],
template_name='blog1.html')),
and in blog1.html:
{% extends "index.html" %}
{% block blog %}
{% for post in blog_post %}
<div id="blog-wrapper" class="bgrid-third s-bgrid-half mob-bgrid-whole group">
<article class="bgrid">
<h5>{{ post.date }} </h5>
<h3><div class = "entry-title">{{ post.title }}</div></h3>
<p>{{ post.user }}</p>
<p><div class = "post_body">{{ post.body|safe|linebreaks }}</div></p>
</article>
</div>
{% endfor %}
{% endblock %}
{% block member %}
Here when I go to the url,I can see all blogs I write,but now I want to see blogs and members(another app) on one page, so how can I do this?
I would suggest you to use ListView's get_context_data method.
Create view in your project's views.py:
from django.views.generic import ListView
# Import your models here.
class HomepageView(ListView):
model = Post
ordering = '-date'
template_name = 'blog1.html'
context_object_name = 'posts'
def get_context_data(self, **kwargs):
context = super(HomepageView, self).get_context_data(**kwargs)
context['members'] = Member.objects.all()
return context
def get_queryset(self):
return super(HomepageView, self).get_queryset()[:10]
Then, change urls.py:
from django.conf.urls import url
# Import ``HomepageView`` here.
urlpatterns = [
url(r'^$', HomepageView.as_view(), name='homepage'),
# Other patterns here.
]
Now you can access posts using posts variable and members using members variable.
from .models import Post
from member.models import UserProfile
def get_data():
return {
"post": Post.objects.all().order_by("-date")[:10],
"user": UserProfile.objects.all()[:10]
}
then in my blog1.html:
{% extends "index.html" %}
{% block blog %}
{% for post in object_list.post %}
<div id="blog-wrapper" class="bgrid-third s-bgrid-half mob-bgrid-whole group">
<article class="bgrid">
<h5>{{ post.date }} </h5>
<h3><div class = "entry-title">{{ post.title }}</div></h3>
<p>{{ post.user }}</p>
<p><div class = "post_body">{{ post.body|safe|linebreaks }}</div></p>
</article>
</div>
{% endfor %}
{% endblock %}
{% block member %}
{% for post in object_list.user %}
<div class="bgrid member">
<div class="member-header">
<div class="member-pic">
<img src="{{ post.portrait }}" alt=""/>
</div>
<div class="member-name">
<h3>{{ post.user }}</h3>
<span>Creative Director</span>
</div>
</div>
<p>{{ post.intro }}</p>
<ul class="member-social">
<li><i class="fa fa-google-plus"></i></li>
<li><i class="fa fa-github"></i></li>
</ul>
</div> <!-- /member -->
{% endfor %}
{% endblock %}