Before I go into detail, here is the line from the html document that results in the error, as well as views.py and urls.py:
<input class="search" type="text" name="q" placeholder="Search Encyclopedia" action="{% url 'encyclopedia:findpage' %}" method="get">
(Yes there is a space betweeen url and 'encyclopedia:findpage')
views.py findpage function:
def findpage(request, name):
pages = util.list_entries()
wanted_pages = set()
wanted_page = None
for page in pages:
if not wanted_page and page == name:
wanted_page = util.get_entry(name)
continue
if name in page:
wanted_pages.add(page)
if wanted_page:
return render(request, 'encyclopedia/page.html', {
"title": name,
"entry": wanted_page
})
if wanted_pages and not wanted_page:
return render(request, 'encyclopedia/index.html', {
"entries": wanted_pages
})
else:
return render(request, 'encyclopedia/noresults.html')
urls.py:
from django.urls import path
from . import views
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("<str:name>", views.wikipage, name="wikipage"),
path("<str:name>", views.findpage, name='findpage'),
path("create", views.newpage, name="newpage")
]
When I run the Django project, I get a NoReverseMatch at /. The error from the webpage reads:
In template /home/quinn/Desktop/cs50web/pset1/wiki/encyclopedia/templates/encyclopedia/layout.html, error at line 17 Reverse for 'findpage' with no arguments not found. 1 pattern(s) tried: ['(?P<name>[^/]+)$']
Line 17 is the piece of html I left at the top of this page. I've checked numerous sources in an attempt to fix this, but I cannot figure it out.
You need to specify a name because your url needs it here:
path("<str:name>", views.findpage, name='findpage')
You can specify kwargs in the url tag in your template like this:
{% url 'reverse:lookup' kwarg='insert here the value that needs to get passed in your url' %}
Related
I'm working on an app that allows the user to create, show and edit an entry. right now i'm working on the editing function. what i'm trying to do is have an edit button (that's actually a form that sends data via hidden inputs) that sends the title of the entry to a view called trans whose sole purpose is redirect to the edit view, the reason i did this is so that when i'm working on the edit view, i can simplify the process where if the request method is GET it shows the page with the form where the user can edit the entry and if it's post the edit view can receive the changes and save them without worrying about the redirecting from the entry's page.
The problem lies in the fact that everytime i click the edit button i get the error:
NoReverseMatch at /wiki/trans
Reverse for 'edit' with keyword arguments '{'title': 'Python'}' not found.
I have checked over and over for any misspellings or issues in urls.py or any problems with the naming but i just can't find the bug. and it's frustrating because i thought that this would be the easiest part of the project.
Below is the relevant code. i would be extremely grateful for anyone who points out what i'm doing wrong. Thank you in Advance.
HTML
<div id="edit">
<form action="{% url 'wiki:trans' %}" method="POST">
{% csrf_token %}
<input type=hidden value={{title}} name="title">
<input type=submit value="Edit">
</form>
</div>
views.py
class EntryForm(forms.Form):
title = forms.CharField(label="Title")
content = forms.CharField(widget=forms.Textarea)
def trans(request):
title = request.POST.get("title")
return redirect("wiki:edit", title=title)
def edit(request, title):
if request.method == "GET":
entry = util.get_entry(title)
return render(request, "encyclopedia/edit.html", {
"form": EntryForm({
"content": entry,
"title": title
})
})
else:
form = EntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return redirect("wiki:title", title=title)
urls.py
app_name = "wiki"
urlpatterns = [
path("", views.index, name="index"),
path("search", views.search, name="search"),
path("new", views.new, name="new"),
path("trans", views.trans, name="trans"),
path("edit", views.edit, name="edit"),
path("random", views.rand, name="random"),
path("<str:title>", views.title, name="title")
]
Try adding a / at the end of each url, like this:
urls.py:
app_name = "wiki"
urlpatterns = [
path("", views.index, name="index"),
path("search/", views.search, name="search"),
path("new/", views.new, name="new"),
path("trans/", views.trans, name="trans"),
path("edit/", views.edit, name="edit"),
path("random/", views.rand, name="random"),
path("<str:title>/", views.title, name="title")
]
Also try using reverse and passing in the title as an arg on your views.py:
return redirect(reverse('wiki:title', args=[title]))
I am new in Django and try to make a quick search engine, but I have this error and cannot fix it after reading Django documentation. Could anyone help me? Thanks.
This is the error:
Reverse for 'search' with no arguments not found. 1 pattern(s) tried: ['(?P<name>[^/]+)$']
My codes are as below:
layout.html
<form method="POST" action="{% url 'encyclopedia:search' %}">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
<input type="submit" value="Go">
</form>
urls.py
from django.urls import path
from . import views
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("<str:name>", views.entry, name="entry"),
path("<str:name>", views.search, name="search")
]
views.py
def search(request, searched_name):
"""
Deal with search engine on the left widget
"""
result = util.get_entry(searched_name)
if result:
return HttpResponseRedirect(reverse('encyclopedia:entry', args=(result)))
return render(request, "encyclopedia/error.html", {
"error_name": "Requested page not found"
})
Your second and third urls the same that's why only one pattern is tried and given the pattern named search isn't the first one, django is unable to find a reverse match. The URLs aren't well thought as they will both match any string after the root of the domain and this will definitely become a nightmare as your project grows bigger. Consider having them as below:
urlpatterns = [
...
path("entry/<str:name>", views.entry, name="entry"),
path("search/<str:name>", views.search, name="search")
]
As per your urls.py, you need to name in URL itself.
I will suggest you to remove name from urls.py and get in views via form data. Please see an example below
urls.py -> path("search/", views.search, name="search")
def search(request):
"""
Deal with search engine on the left widget
"""
result = util.get_entry(request.POST.get('q', None))
if result:
return HttpResponseRedirect(reverse('encyclopedia:entry', args=(result)))
return render(request, "encyclopedia/error.html", {
"error_name": "Requested page not found"
})
I have a project to build a Wiki page in Django and I require to process a word sent from a search field and display its information on screen in case the word matches the stored information. For this I want to send a parameter with "POST" method from the following html template.
<form action="{% url 'wiki:index' %}" method="post">
{% csrf_token %}
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
<input type="submit">
</form>
The idea is for the parameter to be received by the following functions of my file views.py written in Django.
def index(request):
if request.method == "POST":
title = request.POST["q"]
return redirect("wiki:languages")
else:
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
def languages(request, title):
return render(request, "encyclopedia/definitions.html", {
"title": util.get_entry(title)
})
This file has the next header sentences:
from django import forms
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.urls import reverse
from . import util
The "Languages" function in turn processes the get_entry(title) function of the "util.py" code
def get_entry(title):
"""
Retrieves an encyclopedia entry by its title. If no such
entry exists, the function returns None.
"""
try:
f = default_storage.open(f"entries/{title}.md")
return f.read().decode("utf-8")
except FileNotFoundError:
return None
I have the following paths indicated in the file "urls.py"
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:title>", views.languages, name="languages"),
]
This is intended to display the contents of the "file. md" found within the "entries" directory and whose name matches the text typed in the search field of the html template. In doing so, however, it displays the following error:
NoReverseMatch at /
Reverse for 'languages' with no arguments not found. 1 pattern(s) tried: ['wiki/(?P<title>[^/]+)$']
Request Method: POST
Request URL: http://127.0.0.1:8000/
Django Version: 3.1.2
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'languages' with no arguments not found. 1 pattern(s) tried: ['wiki/(?P<title>[^/]+)$']
I tried to use the parameter "form" but maybe I didn’t know how to use it and I didn’t achieve the goal.
I hope you can help me modify my functions in Django and html to properly use the function "get_entry(title)" and display the contents of the file ".md" that matches the information typed.
I've been following the instructions here.
This is the error it gives me, when i try to run it on localhost:
Page not found (404)
Request Method: GET
Request URL: http://localhost:7000/account.html
Using the URLconf defined in gettingstarted.urls, Django tried these URL patterns, in this
order:
[name='index']
[name='account']
db/ [name='db']
admin/
^celery-progress/
The current path, account.html, 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.
This is what i have in my urls.py
urlpatterns = [
path("", hello.views.index, name="index"),
path("", hello.views.account, name="account"),
path("db/", hello.views.db, name="db"),
path("admin/", admin.site.urls),
re_path(r'^celery-progress/', include('celery_progress.urls'))
]
This is what i have in views.py
def account(request):
if request.method == 'POST':
form = AccountForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('loading.html')
else:
form = Nameform()
return render(request, 'account.html', {'form': form})
Finally this is the form itself(account.html):
<form action="/account/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
I have the feeling i'm missing something really simple but i can't for the life of me see it. Any help would be greatly appreciated.
First, you need to change the URL patterns, because multiple views (hello.views.index and hello.views.account) are pointing towards the same pattern
urlpatterns = [
path("index/", hello.views.index, name="index"),
path("account/", hello.views.account, name="account"),
path("db/", hello.views.db, name="db"),
path("admin/", admin.site.urls),
re_path(r'^celery-progress/', include('celery_progress.urls'))
]
then, access the URL, http://localhost:7000/account/
You are requesting for the url that could match the string /account/ but in your urlpatterns variable you have an empty string so it can't match anything.
Remember that the first argument of urlpatterns is a pattern string that can be matched with regex.
Perhaps you could map it like:
path("/account/", hello.views.account, name="account")
Project Name: JalaBapa_website
JalaBapa_website\urls:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^about_us/', include('About_Us.urls')),
url(r'^activities/', include('Activities.urls')),
url(r'^collections/', include('Collections.urls')),
url(r'^contact_us/', include('Contact_Us.urls')),
url(r'^donate/', include('Donate.urls')),
url(r'^events/', include('Events.urls')),
url(r'^home/', include('Home.urls')),
url(r'^publications/', include('Publications.urls')),
]
Publications/urls.py:
from django.conf.urls import url
from . import views
app_name = "Publications"
urlpatterns = [
# /publications/
url(r'^$', views.publications, name='publications'),
# /publications/Xyz_9999.pdf/
url(r'(?P<file_name>^[A-Z][a-z]+\_[0-9]{4}\.pdf$)', views.pdfs, name='pdfs')
]
Publications/views.py
from django.http import HttpResponse, FileResponse
from django.shortcuts import get_object_or_404, render
from .models import *
# Create your views here.
def publications(request):
all_files = Publications.objects.all()
uploaded_file_names = []
for obj in all_files:
uploaded_file_names.append(str(obj.file_name()))
context = {
'uploaded_file_names': uploaded_file_names
}
return render(request, 'publications/publications.html', context)
def pdfs(request, file_name):
with open('media/pdfs/'+file_name, 'r') as pdf:
response = FileResponse(pdf, content_type='application/pdf')
return response
some code of: Publications/templates/publications/publications.html
<div class="container-fluid">
{% for file_name in uploaded_file_names %}
<a href="{{ file_name }}">
<!-- <a href="{% url 'Publications:pdfs' file_name %}">
will be continued...
the above line in snippet was COMMENTED BECAUSE BEFORE THIS WAS SHOWING ERROR :
NoReverseMatch at /publications/
Reverse for 'pdfs' with arguments '('July_2017',)' not found. 1 pattern(s) tried: ['publications/(?P^[A-Z][a-z]+\_[0-9]{4}\.pdf$)']
Here is Error Screen Shot image
I WOULD LIKE TO KNOW WHY THIS IS NOT WORKING - QUESTION 1
ANYHOW, <a href="{{ file_name }}"> was hardcoded but running so I moved on temporarily
Continuing the above file left half way...
<div style="float: left;" class="boxes black-container text-grow">
{{ file_name }}
</div>
</a>
{% endfor %}
</div>
QUESTION - 2: In just above file publications.html, when I click on {{ file_name }}, it shows me error 404 page not found, here is screen shot of that page
The Link: 127.0.0.1:8000/publications/July_2017
The url matching is: url(r'^publications/', include('Publications.urls')) and url(r'(?P<file_name>^[A-Z][a-z]+\_[0-9]{4}\.pdf$)', views.pdfs, name='pdfs')
While, when I went on https://www.regextester.com/88429 website it shows me that my file_name : July_2017.pdf matches with Regular Expression : ^\[A-Z\]\[a-z\]+\_\[0-9\]{4}\.pdf$
This may not be answers - I'm not very confident with django, but I don't have enough reputation to only place a comment.
Question 1. Your placement of the caret ('^') looks different to mine - I've really only ever seen it as the first character inside the quotes (e.g. r'^publications/(?P etc etc. I can't see that this would cause the problem, but it might be something to try.
Question 2, the view 'pdfs' is trying to serve a FileResponse object but is your filename variable ('July_2017') stripped of the '.pdf' extension that will allow it to hit the file successfully?