Django: - NoReverseMatch error - python

I'm following the djangoforgirls.org tutorial on making my first django site. I'm trying the stage "extending your template" to make a link to an article within my website that uses the general template.
I keep get thrown the error: "NoReverseMatch at /, Reverse for 'post_detail' with arguments '()' and keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['post/(?P\d+)/$']"
Some variable and file names may seem strange, the use of the website was music sampling but I used the tutorial's names for things in case that was what was wrong.
My urls.py for entire project:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('sample.urls')),
]
My urls.py for the specific app (sample):
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
url(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),
]
My views.py for the app:
from django.utils import timezone
from .models import AudioSample
from django.shortcuts import render, get_object_or_404
def post_list(request):
samples = AudioSample.objects.order_by('length')
return render(request, 'blog/post_list.html', {'samples': samples})
def post_detail(request, pk):
post = get_object_or_404(AudioSample, pk=pk)
return render(request, 'blog/post.html', {'post': post})
And the line of code from the base template that's the link to another page in the website:
How to sample
I saw another person that asked this question with a similar project here and got it fixed but I dont understand the answer enough to make the change to mine (I dont understand what the namespace is).

If you have more than one urls.py, namespace can tell django how to handle the request. So in normally, namespace is the APP name.

In your project urls.py, try replacing r'' with r'^'. The former matches all urls, while the latter matches the start of the string.

Related

Django Tutorial. Page not found

I already search for any answer which could help me before write this question, but I haven't found anything that helps.
The thing is that I follow the tutorial and I can't see the view that I created.
Now I'm going to share my code:
project urls.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
polls urls.py:
from django.urls import path
from . import views
urlpatterns = [
path(" ", views.index, name='index'),
#127.0.0.1/polls/
]
polls views.py
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
def index(request):
HttpResponse("Welcome to de Polls Universe Index")
OK I ALREADY KNOW WHATS GOING ON:
I forgot the RETURN before de HttpResponse.
There are two issues with your code:
The path for the index view contains a blank, which must be removed
The view function must return a response object. Please add return in front of the last line.

Trying to reach url with Path include() shows 404 in Django

first of I want to apologize if I use the wrong terms or words in my question. I'm completely new to Django and got only a few months of experience with python. I hope you can understand my question anyways. I also want to acknowledge the fact that I'm using some imports that are not needed here and might not be relevant to the latest version of Django, I'm starting to get lost in all the things I've tried from other threads to solve my problem.
I'm having some problems with showing a page from apps url.
I'm getting redirected to my homepage when trying to reach localhost:8000/articles (because /articles gives 404 error)
I'm not sure exactly what code I need to include here, so bear with me.
articles/urls.py and articles/views.py
from django.conf.urls import url
from django.urls import include, path
from django.conf.urls import include, url
from django.urls import path
from .import views
urlpatterns = [
path('^$', views.article_list),
]
from django.shortcuts import render
from django.http import HttpResponse
# views
def article_list(request):
return render(request, "articles/article_list.html")
The project's urls.py and project's views.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from django.urls import include, path
from django.conf.urls import include, url
from django.urls import path, re_path
from .import views
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('articles.urls')),
path('about/', views.about),
re_path('^.*$', views.homepage)
]
from django.http import HttpResponse
from django.shortcuts import render
#Views
def homepage(request):
# return HttpResponse('homepage')
return render(request, "homepage.html")
def about(request):
# return HttpResponse('about')
return render(request, "about.html")
Im getting no errors or such.
So, my question is - does anybody have a clue why /articles generate 404 error?
Thank you in advance.
Firstly, don't use ^$ with path(). You only use regular expressions with re_path.
path('', views.article_list),
Usually, /articles will be redirected to /articles/ with a trailing slash.
However, in your case, you have a catch-all pattern:
re_path('^.*$', views.homepage)
This matches /articles, so you see the home page. Note it's not redirected as you say in your answer, the browser bar will still show /articles.
Unless you have a really good reason to have the catch all, I suggest you remove it and change it to
re_path('^$', views.homepage),
or
path('', views.homepage),
That way, you'll see the homepage for localhost:8000, localhost:8000/articles will be redirected to localhost:8000/articles/, and you'll get a 404 for pages that don't exist, e.g. localhost:8000/art/
Just using a empty string '' instead of '^$:
urlpatterns = [
path('', views.article_list),
]
Take a look at the last example here: https://docs.djangoproject.com/en/3.1/topics/http/urls/#url-namespaces-and-included-urlconfs
*I don't know what django version are you using, but for regular expressions paths you should use re_path() https://docs.djangoproject.com/en/3.1/ref/urls/#django.urls.re_path

Django - creating a random page selector

I'm hoping to create a link on a homepage that, when clicked, will randomly redirect the user to 1 out of 5 entry pages (CSS, Django, Git, HTML, Python) on the site.
I saw someone else asking essentially the same question (select an random page with django) and I tried to follow the 2 answers but now when I click on my Random Page link I have an error:
NoReverseMatch at /wiki/random/
Reverse for 'index' with arguments '('Git',)' not found. 2 pattern(s) tried: ['wiki/random/$', 'wiki/$']
Request Method: GET
Request URL: http://127.0.0.1:8000/wiki/random/
Exception Type: NoReverseMatch
views.py
from django.urls import reverse
from django.http import HttpResponseRedirect
from . import util
import random
def random_page (request):
entries = util.list_entries()
selected_page = random.choice(entries)
return HttpResponseRedirect (reverse('index', args=[selected_page]))
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("css/", views.css, name="CSS"),
path("django/", views.django, name="Django"),
path("git/", views.git, name="Git"),
path("html/", views.html, name="HTML"),
path("python/", views.python, name="Python"),
path("createnew/", views.createnew, name="New_Entry"),
path("random/", views.random_page, name="index")
]
layout.html
<div>
Random Page
</div>
I was a little worried about making the homepage and random_page have the same name "index" but even when I changed the name in views.py to "random" and then changed it in layouts.html it still didn't work.

Django Tutorial "Write Views That Actually Do Something"

I've been working on the Django tutorial. I'm on the part where it is "Write Views That Actually Do something." (Part 3)
I'm trying to use the index.html template that it gives you, but I keep getting a 404 error that says
Request Method: GET
Request URL: http://127.0.0.1:8000/polls/index.html
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^polls/ ^$ [name='index']
^polls/ ^(?P<question_id>\d+)/$ [name='detail']
^polls/ ^(?P<question_id>\d+)/results/$ [name='results']
^polls/ ^(?P<question_id>\d+)/vote/$ [name='vote']
^admin/
The current URL, polls/index.html, didn't match any of these.
I don't know if one of the regex are wrong? I've been messing around with it for a while now and I have had no luck getting it to work.
I can go to /polls just fine. But /polls/index.html does not work.
Any help would be appreciated.
The version of Django that I'm using is 1.7.4
Django view functions or classes use the template you define, so that you do not have to specify it in the URL. The urls.py file matches your defined regex to send requests to views.
If you truly wanted to use that URL, you would have to define ^polls/index.html$ in your urls.py and direct it to your view.
From what you're asking it sounds like you essentially want to output a static html file on a URL defined in your urlpatterns in urls.py.
I strongly suggest you take a look at Class Based Views.
https://docs.djangoproject.com/en/1.7/topics/class-based-views/#simple-usage-in-your-urlconf
The quickest way to go from what you've got, to rendering polls/index.html would be something like;
# some_app/urls.py
from django.conf.urls import patterns
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^polls/index.html', TemplateView.as_view(template_name="index.html")),
)
But I'm sure you'll want to pass things to the template so class based views will be what you need. So the alternative to the above with added context would be;
# some_app/views.py
from django.views.generic import TemplateView
class Index(TemplateView):
template_name = "index.html"
def get_context_data(self, **kwargs):
context = super(Index, self).get_context_data(**kwargs)
context['foo'] = 'bar'
return context
Then obviously adding {{ foo }} to your index.html would output bar to the user. And you'd update your urls.py to;
# some_app/urls.py
from django.conf.urls import patterns
from .views import Index
urlpatterns = patterns(
'',
(r'^polls/index.html', Index.as_view()),
)

What more do I need to do to have Django's #login_required decorator work?

I am trying to use Django's account system, including the #login_required decorator. My settings.py file includes django.contrib.auth and I have done a syncdb.
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/accounts/login/?next=/
Using the URLconf defined in dashboard.urls, Django tried these URL patterns, in this order:
^$ [name='home']
The current URL, accounts/login/, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
I see the above after trying to #login_required-decorate my home view.
It seems to be choking because it is redirected to accounts/login/, which I have not prepared for in my urls.py.
What can I add to urls.py or elsewhere so that the login_required decorator will do its usual behaviour?
Thanks,
Set the LOGIN_URL in your settings. The default value is '/accounts/login/'
The decorator also takes an optional login_url argument:
#login_required(login_url='/accounts/login/')
And, from the docs:
Note that if you don’t specify the login_url parameter, you’ll need to
ensure that the settings.LOGIN_URL and your login view are properly
associated. For example, using the defaults, add the following line to
your URLconf:
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
path('accounts/login/', admin.site.urls),
Add this line in your urls.py project folder. Then it will work fine.
from django.contrib.auth.decorators import login_required
#login_required(login_url='/accounts/login/')
Add above two lines in your views.py file.
What worked for me in Django 2.2.1 - include re_path('^accounts/', admin.site.urls), in my project urls.py:
urls.py
from django.conf import settings
from django.conf.urls import include
from django.conf.urls import re_path
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^accounts/', admin.site.urls),
]
And in my views.py:
views.py
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
#method_decorator(login_required, name='dispatch')
class HomePageView(TemplateView):
"""
Home Page View
"""
template_name = 'amp/home.html'
Hope that helps.
UPDATE: To avoid warnings from django in regards to admin urls being loaded twice, I used a redirect instead in urls.py:
urls.py
urlpatterns = [
re_path('^accounts/', admin.site.urls),
re_path(r'^admin/', RedirectView.as_view(url='/accounts/', permanent=True))
]
More on redirect view here.

Categories

Resources