This is the extention of the same problem i asked about in a previous question.
The problem i'm having here now is that after fixing the problem with the trans views function and expecting the program to run without problems, i get the following error
NoReverseMatch at /wiki/Python/edit
Reverse for 'edit' with keyword arguments '{'title': ''}' not found.
Which i can't for the life of me understand considering that i AM passing the title argument in the html and set up the edit views function and the urlpath in urls.py to expect the title argument.
when i take a closer look at the traceback, it highlights this block of code from the edit views function.
return render(request, "encyclopedia/edit.html", {
"form": EntryForm(initial={
"title": title,
"content": entry
})
})
but i don't understand what the problem is here?
this is the final part of the project i'm working on so i'll be very grateful for any and all help.
below is the relevant code.
HTML
entry.html
<!-- The edit button in the entry's page -->
<form action="{% url 'wiki:trans' %}" method="POST">
{% csrf_token %}
<input type=hidden value={{title}} name="title">
<input type=submit value="Edit">
</form>
edit.html
<!-- the edit page -->
{% block body %}
<h1>Edit Entry</h1>
<br>
<form action="{% url 'wiki:edit' title=title %}" method="POST">
{% csrf_token %}
{{form}}
<input type="submit" value="Save" id="save">
</form>
{% endblock %}
view.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(initial={
"title": title,
"content": entry
})
})
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("<str:title>/edit", views.edit, name="edit"),
path("random", views.rand, name="random"),
path("<str:title>", views.title, name="title")
]
def edit(request, title):
if request.method == "GET":
entry = util.get_entry(title)
return render(request, "encyclopedia/edit.html", {
"form": EntryForm(initial={
"title": title,
"content": entry
})
})
That render() call is not passing a value for title, therefore the template tries to use a blank value, which is not allowed.
The title var that you are passing to title=title dict is empty that means that the title variable has no data. To fix it make sure that title has a value or change that as optional argument in the url patterns.
You can fix it doing the following:
def edit(request, title=None):
Then title will take a default value if you don't pass it.
Related
My path looks like so:
path('edit/<str:entry_name>/', views.edit, name='edit').
I want to access this path through a form like so:
<form action="{% url 'edit' entry_name=entry_title %}" method="get">
{% csrf_token %}
<input type="hidden" name="title" value="{{ entry_title }}">
<input type="hidden" name="content" value="{{ entry_content }}">
<input type="submit" value="Edit">
</form>
But then I get this error: Reverse for 'edit' with keyword arguments '{'entry_name': ''}' not found. 1 pattern(s) tried: ['edit/(?P<entry_name>[^/]+)/\\Z'].
It seems like entry_name is empty, but I use the entry_name parameter elsewhere on the page and it works fine.
{% block title %}
{{ entry_title }}
{% endblock title %}
is not empty, since I can see the titel on the tab-title.
EDIT:
Here are the views:
To access the entry page where the form is located:
def entry(request, title):
entry = util.get_entry(title)
if entry is None:
return render(request, "encyclopedia/error.html", {
"error_name": "Not Found",
"error_message": f"{title} page Not Found"
})
return render(request, "encyclopedia/entry.html", {
"entry_title": title,
"entry_content": markdown2.markdown(entry)
})
The edit view:
def edit(request, entry_name):
if request.method == "POST":
query_dict = request.POST
new_entry_name = entry_name
content = query_dict.get("content")
util.save_entry(new_entry_name, content)
entry = util.get_entry(new_entry_name)
if entry is not None:
return HttpResponseRedirect(f"/wiki/{new_entry_name}/")
else:
return HttpResponse("Oop something went wrong there")
return render(request, "encyclopedia/entry.html", {
"error": "",
"title": entry_name,
"content": request.GET.get("content")
})
You can try to change your form action bcs i`ve never seen someone doing '=' while giving an id or slug in action
try this:
<form action="{% url 'edit' entry_title %}" method="get">
And btw can you add your models and views.py for better understanding
NoReverseMatch at /search/
Reverse for 'entry' not found. 'entry' is not a valid view function or pattern name.
I´m trying to make an search engine for my website in django, via views.py, but Django always says that there's an exception in views.py
Views.py
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
def entries(request, entry):
if entry not in util.list_entries():
raise Http404
content = util.get_entry(entry)
return render(request,"encyclopedia/entry.html",
{"title": entry, "content": Markdown().convert(content)},
)
def search(request):
query = request.GET.get("q", "")
if query is None or query == "":
return render(
request,
"encyclopedia/search.html",
{"found_entries": "", "query": query},
)
entries = util.list_entries()
found_entries = [
valid_entry
for valid_entry in entries
if query.lower() in valid_entry.lower()
]
if len(found_entries) == 1:
return redirect("entry", found_entries[0])
return render(
request,
"encyclopedia/search.html",
{"found_entries": found_entries, "query": query},
)
But Django says: "if len(found_entries) == 1:
return redirect("entry", found_entries[0])
have an "NoReverseMatch" error"
Urls.py
from django.urls import path
from . import views, util
urlpatterns = [
path("", views.index, name="index"),
path("entries/<str:entry>", views.entries, name="entries/{{ entry }}"),
path("search/", views.search, name="search"),
]
handler404 = 'encyclopedia.views.error_404_view'
Layout.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<body>
<div class="row">
<div class="sidebar col-lg-2 col-md-3">
<h2>Wiki</h2>
<form action="{% url 'search' %}">
<input class="search" type="text" name="q" placeholder="Search
Encyclopedia">
</form>
<div>
Home
</div>
<div>
Create New Page
</div>
<div>
Random Page
</div>
{% block nav %}
{% endblock %}
</div>
<div class="main col-lg-10 col-md-9">
{% block body %}
{% endblock %}
</div>
</div>
</body>
</html>
I've been trying a lot of things, but nothing fix it, how I can let my page run well?
You must change your url name in urls.py to entry:
path("entries/<str:entry>", views.entries, name="entry"),
And you should pass the argument in your views.py file as:
return redirect("entry", entry=found_entries[0])
See https://docs.djangoproject.com/en/4.0/topics/http/shortcuts/#redirect
I am working on CS50 Project 1 dealing with Django. In urls.py I have two paths that take strings as input, but neither work, and I receive a NoReverseError message.
urls.py code
urlpatterns = [
path("", views.index, name="index"),
path("edit_entry/<str:title>/", views.edit_entry, name = "edit_entry"),
path("search/", views.search, name = "search"),
path("wiki/<str:title>/", views.get_entry, name = "get_entry"),
path("create_entry", views.create_entry, name = "create_entry")
]
views.get_entry code
def get_entry(request, title):
exists = util.get_entry(title)
if exists is None:
return render(request, "encyclopedia/get_entry.html", {
"entry": "Entry Does Not Exist"
})
else:
entry = markdown(util.get_entry(title))
return render(request, "encyclopedia/get_entry.html", {
"entry": entry
})
views.edit_entry code (edit_entry actually has some more work that needs to be done to it)
def edit_entry(request, title):
if request.method == "POST":
form = NewEditEntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return HttpRespnseRedirect("/wiki/" + title)
else: return render(request, "encyclopedia/edit_entry.html",{
"form": NewEditEntryForm() })
The error message
NoReverseMatch at /wiki/Css/
Reverse for 'edit_entry' with keyword arguments '{'title': ''}' not found. 1 pattern(s) tried: ['edit_entry/(?P<title>[^/]+)/$']
Your help would greatly be appreciated. Thank you!
Templates
get_entry.html
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<p>
{{ entry|safe }}
</p>
Edit This Entry
{% endblock %}
edit_entry.html
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit Entry
{% endblock %}
{% block body %}
<h1>Edit {{ title }}</h1>
<form action = "{% url 'edit_entry' title=title %}" method = "POST"></form>
{% csrf_token %}
{{ form }}
<input type = submit value = "Save">
</form>
{% endblock %}
I figured it out. I had to remove title=title from the hrefs in the templates and make it a hard coded url with a variable.
I am fairly new to Django and for my certification, I am working on cloning Wikipedia. I was able to get the wiki and editing commands to work but having difficulties creating new entries. This is my function to create a new entry:
** Main urls.py**
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("encyclopedia.urls"))
]
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path ("wiki/<str:title>", views.entry, name="entry"),
path ("edit/<str:title>", views.edit, name="edit"),
path ("create/<str:title>", views.create, name="create")
]
views.py
class Post(forms.Form):
title = forms.CharField(label= "Title")
textarea = forms.CharField(widget=forms.Textarea(), label='')
def create(request, title):
if request.method == "POST":
form = Post(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
textarea = form.cleaned_data['textarea']
entries : util.list_entries()
if title in entries:
return render(request, "encyclopedia/error.html", {
"form": Search(),
"message": "Page already exists",
"type": "exists"
})
else:
util.save_entry(title,textarea)
page=util.get_entry(title)
page_converted = md.convert(page)
return render(request, "encyclopedia/create.html", {
"form": Search(),
'page': page_converted,
"title": title
})
else:
return render(request, "encyclopedia/create.html", {
"form": Search(),
"post": Post()
})
MY TEMPLATE
Creating a new entry
{% extends "encyclopedia/layout.html" %}
{% block title %}
Create
{% endblock %}
{% block body %}
<form method="post" action="{% url 'create' %}">
{% csrf_token %}
<h4 class="display-2">Create new page:</h4>
<h6 class="post-title">Title: {{post.title}}</h6>
{{post.textarea}}
<br>
<input class="save btn btn-info" type="submit" value="Save"/>
</form>
{% endblock %}
Pop an error if the page already exists/not found
{% extends "encyclopedia/layout.html" %}
{% block title %}
Error
{% endblock %}
{% block body %}
<h1 class="display-2 error">{{message}}</h1>
{% if type == "not_found" %}
<h3>The page {{title}} cannot be found.</h3>
{% endif %}
{% if type == "exists" %}
<h3>The page {{title}} already exists.</h3>
{% endif %}
{% endblock %}
THE ERROR THAT DJANGO RETURNS
NoReverseMatch at /create/HTML
Reverse for 'create' with no arguments not found. 1 pattern(s) tried: ['create/(?P<title>[^/]+)$']
Request Method: GET
Request URL: http://localhost:8000/create/HTML
Django Version: 3.1.2
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'create' with no arguments not found. 1 pattern(s) tried: ['create/(?P<title>[^/]+)$']
Exception Location: /usr/local/Cellar/python#3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/django/urls/resolvers.py, line 685, in _reverse_with_prefix
Python Executable: /usr/local/bin/python
Python Version: 3.8.6
Python Path:
['/Users/amertoukan/Desktop/Projects/cs50/Django/wiki',
'/usr/local/Cellar/python#3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python38.zip',
'/usr/local/Cellar/python#3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8',
'/usr/local/Cellar/python#3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/lib-dynload',
'/Users/amertoukan/Library/Python/3.8/lib/python/site-packages',
'/usr/local/Cellar/python#3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages
What am I doing wrong? Thank you sm in advance.
The reason is that when you create a new entry, you do not have title yet.
You are getting the title and save it to edit it later.
path ("create/", views.create, name="create")
and in views.py
def create(request): # no title.
So the django file is not showing the form and at first, I got angry at that so I just used HTML code to create a form but I realized that when I submit it on the form it does not send it to where I want it to send. I was just wondering if you could help. I think the problem with the file is between the relationship between util.py file and the index.html file but I can't see it for some reason.
Thank you!!
util.py file
class Form(forms.Form):
searched = forms.CharField(max_length=128, help_text="Please enter the category name.")
def get_name(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
searched = form.cleaned_data['searched']
return searched
else:
form = Form
return render(request, "wiki/index.html", {
"form" : form
})
wiki.urls.py - main urls file
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("encyclopedia.urls")),
path('wiki/', include("encyclopedia.wurls"))
]
encyclopedia.urls file
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
views.py file
from django.shortcuts import render
from . import util
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries(),
"lookUp": util.get_name(request)
})
def title(request, name):
return render(request, "encyclopedia/titlePage.html", {
"entries": util.list_entries(),
"name": name,
"entry": util.get_entry(name)
})
index.html file
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block formsearch %}
<form action="/wiki/{{lookUp}}" method="post">
{% csrf_token %}
{{ lookUp }}
<input type="submit" value="Submit">
</form>
{% endblock %}
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li> <a href= "/wiki/{{entry}}" > {{ entry }} </a> </li>
{% endfor %}
</ul>
{% endblock %}
Take away this from util.py:
def get_name(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
searched = form.cleaned_data['searched']
return searched
else:
form = Form
return render(request, "wiki/index.html", {
"form" : form
})
and instead add this to views.py:
def index(request):
if request.method == 'POST':
form = Form(request.POST)
if form.is_valid():
searched = form.cleaned_data['searched']
return searched
else:
form = Form
return render(request, "wiki/index.html", {
"form" : form
})
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries(),
"lookUp": util.get_name(request)
})