NoReverseMatch at /app/detail/3/ - python

I got an error,
NoReverseMatch at /app/detail/3/
Reverse for 'detail' with arguments '('',)' not found. 1 pattern(s) tried: ['app/detail\\/(?P<pk>[0-9]+)\\/$'] .
I wrote in views.py
def top(request):
content = POST.objects.order_by('-created_at')[:5]
page = _get_page(blog_content, request.GET.get('page'))
return render(request, 'top.html',{'content':content,"page":page})
class DetailView(generic.DetailView):
model = POST
template_name = 'detail.html'
in top.html
<div>
{% for content in page %}
<h2>{{ content.title }}</h2>
<p>SHOW DETAIL</p>
{% endfor %}
</div>
in detail.html
<div>
<h2>Comment List</h2>
Comment
{% for comment in post.comment_set.all %} Name:{{ comment.name }}
<br> Text:{{ comment.text }}
<br>
Reply
<br> {% endfor %}
</div>
<div>
<h2>Comment Form</h2>
<form action="" method="POST">
{{ form.as_p }} {% csrf_token %}
<button type="submit">Send</button>
</form>
</div>
in urls.py
urlpatterns = [
path('top/', views.top, name='top'),
path('detail/<int:pk>/', views.DetailView.as_view(template_name='detail.html'), name='detail'),
path('comment/<int:pk>/',views.comment, name='comment'),
path('recomment/<int:pk>/', views.recomment, name='recomment'),
]
When I access top.html, web site is shown correctly , so it is ok. But when I put SHOW DETAIL links, this error happens. I really cannot understand why this error happens.

Related

Django calling methods of DetailView and RedirectView in template

I'm trying to get into Django and got stuck with DeatailView and RedirectView
I made the following template for rendering posts with enabling post detailed view and like button. When I click on either Like or Detail button none of the requests is sent. I tried changing different methods, but that didn't help either. I trying to get whether I was mistaken in the template or in view logic.
{% extends 'base.html' %}
{% block content %}
{% for post in object_list %}
<div class="card" style="width: 40rem;">
<img src = "{{ post.image.url }}" style="height: 40rem;">
<div class="card-body">
<h5 class="card-tittle">{{post.author.username}}</h5>
<p class="card-text">{{ post.description }}</p>
<p class="card-text">Likes : {{ post.likes.count }}</p>
<p class="id">Post_id: {{ post.id }}</p>
<div class="btn-group-vertical">
{% if user.is_authenticated %}
<form action="{% url 'like_post' %}" method="POST">
{% csrf_token %}
<button type="button" class="btn btn-secondary">Like</button>
</form>
{% endif %}
<form action="{% url 'detail' pk=post.id %}" method="GET">
<button type="button" class="btn btn-secondary">Detail</button>
</form>
<!-- <button type="button" class="btn btn-secondary">down</button> -->
</div>
</div>
</div>
{% endfor %}
{% endblock %}
Posts views.py file
class PostDetail(DetailView):
model = Post
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
print(context.items())
return context
class PostLikeUpvote(RedirectView):
def get_redirect_url(self, *args, **kwargs):
post_id = kwargs.get('id')
post = get_object_or_404(Post, id=post_id)
user = self.request.user
if user.is_authenticated():
post.likes.add(user)
url_redirect = post.get_redirect_url()
return url_redirect
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accounts.urls')),
path('new/', PostCreate.as_view(), name='new'),
path('', PostList.as_view(), name='list'),
path('posts/', PostList.as_view(), name='list'),
path('like_post/', PostLikeUpvote.as_view(), name='like_post'),
path('posts/<pk>/', PostDetail.as_view(), name='detail'),
path('bot/webhook', csrf_exempt(BotView.as_view())),
]
Any comments are appreciated.
In order to submit the form, the type of the button should be submit, not button:
{% if user.is_authenticated %}
<form action="{% url 'like_post' %}" method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-secondary">Like</button>
</form>
{% endif %}
otherwise it is a simple button that can for example run a JavaScript function, but it will not (automatically) submit the form. Of course you can write a JavaScript function to submit the form, but unless you have a specific reason for that, it is better to let the browser do the work for you.

NoReverseMatch with django

Hey I did build a website two weeks ago and it worked perfectly fine but when I am trying to open it without any changes the NoReverseMatch found error pops up. I do not understand why. Μy view for the auswertung method is defined as auswertung(request, pk)
This is my url code:
urlpatterns = [
url(r'^$', views.main_page, name='main_page'),
url(r'^machine/(?P<pk>\d+)/$', views.auswertung, name='auswertung'),
url(r'^add$', views.add_machine, name='add_machine'),
url(r'^delete$', views.delete_machine, name='delete_machine'),
url(r'^machine/(?P<pk>\d+)/edit/$', views.edit_machine, name='edit_machine')]
and this is the template which is producing the error:
{% block content %}
<div>
<form class="MainFormClass" method="POST">
{% csrf_token %}
{{ form }}
<button type="submit" class="save btn btn-default">Submit</button>
</form>
<ol class="orderdList">
{% for machine in machines_only %}
<p class="list-item">{{ machine.status.machine_number }}
<a href="{% url 'auswertung' pk=machine.status.machine_number %}">
{{ machine.status.machine_description }}
</a>
<img class="main-imageClass" src="{{machine.overallsrc}}"/>
</p>
{% endfor %}
</ol>
</div>
{% endblock %}
I hope somebody can help me.

I do not understand this Django error

Error during template rendering
In template
C:\Users\Paddy\Desktop\Django-tut\mysite\blog\templates\blog\post_list.html,
error at line 10 Reverse for 'post_detail' with arguments '()' and
keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried:
['blog/post/(?P[0-9]+)/$']
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<!--<h1>{{ post.title }}</h1>-->
<p>{{ post.text|linebreaks }}</p>
</div>
{% endblock %}
My post_detail.html file looks like this
{% extends 'blog/base.html' %}
{% block content %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endblock %}
My urls.py is
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
url(r'^post/(?P<pk>[0-9]+)/$', views.post_detail, name='post_detail'),
]
and views.py is
from django.shortcuts import render
from django.utils import timezone
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
#Post.objects.get(pk=pk)
# Create your views here.
def post_list(request):
return render(request, 'blog/post_list.html', {})
Thanks.
Assuming the first template you've posted is post_list.html you don't send any context variables to it.
In post_list view - if you want to list all posts - you have to add:
def post_list(request):
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
Then in your post_list.html template you have to loop over posts:
{% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %} # iterate over posts
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
{% endblock %}
There error message complains that it can't find a reverse URL when pk is '', the empty string.
Indeed there is no URL that matches that, as the regular expression required [0-9]+, and the empty string doesn't match that. So a reverse match can't be found.
The reason why pk was empty is explained in the other answer.

Django dynamic homepage

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 %}

Python Django from does not work after refactoring

I have been working through the Tango With Django tutorial. However, I noticed that some of the examples did not adhere to what people consider Django best practices, so I went back to do a little refactoring. Here is how I first wrote a template for a form that allows a user to add a web page to a category.
<!DOCTYPE html>
<html>
{% extends 'rango/base.html' %}
{% block title %}Add a Page{% endblock %}
{% block body_block %}
<h1>Add a Page</h1>
<form id="page_form" method="post" action="/rango/category/{{ category_name }}/add_page/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<input type="submit" name="submit" value="Create Page"></input>
</form>
{%endblock%}
</html>
I then refactored the template like so:
<!DOCTYPE html>
<html>
{% extends 'rango/base.html' %}
{% block title %}Add a Page{% endblock %}
{% block body_block %}
<h1>Add a Page</h1>
<form id="page_form" method="post" action="{% url 'add_page' category_name %}"></form>
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<input type="submit" name="submit" value="Create Page"></input>
</form>
{%endblock%}
</html>
However, now when I click the submit button, nothing happens. Here is the url pattern that I use:
url(r'^category/(?P<category_name_url>\w+)/add_page/$', views.add_page, name='add_page')
Here is my view:
#login_required
def add_page(request, category_name_url):
category_name = remove_underscores(category_name_url)
if request.method == 'POST':
form = PageForm(request.POST)
if form.is_valid():
page = form.save(commit=False)
try:
cat = Category.objects.get(name=category_name)
page.category = cat
except Category.DoesNotExist:
return render(request, 'rango/add_page.html', {})
page.views = 0
page.save()
return category(request, category_name_url)
else:
print form.errors
else:
form = PageForm()
return render(request, 'rango/add_page.html',
{'category_name_url': category_name_url,
'category_name': category_name,
'form': form})
UPDATE:
Here is the code in urls.py:
from django.conf.urls import patterns, url
from rango import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^about$', views.about, name='about'),
url(r'^add_category/$', views.add_category, name='add_category'),
url(r'^category/(?P<category_name_url>\w+)/$', views.category, name='category'),
url(r'^category/(?P<category_name_url>\w+)/add_page/$', views.add_page, name='add_page'),
url(r'^register/$', views.register, name='register'),
url(r'^login/$', views.user_login, name='login'),
url(r'^restricted/$', views.restricted, name='restricted'),
url(r'^logout/$', views.user_logout, name='logout'),
)
UPDATE:
I print out the result of {% url 'add_page' category_name %} and got /rango/category/Ruby/add_page/, which is the correct result. Looks like the url tag is resolving to the correct path. Still not sure why it is not working.
OMG! I feel so lame! This line was the issue:
<form id="page_form" method="post" action="{% url 'add_page' category_name %}"></form>
The fields and submit button were not enclosed in the form! Ugh!

Categories