I'm new to Django and I'm making wiki website based on markdown. I am having one problem. Django can't match the path in html to urls.py. It happens when I try to open wiki entries. It gives me the following error. I have already passed the parameter to 'page', I honestly have no idea what to do.
Using the URLconf defined in wiki.urls, Django tried these URL patterns, in this order:
admin/
[name='index']
wiki/<str:page> [name='page']
search [name='search']
create [name='create']
addentry [name='add_entry']
nomatches [name='nomatches']
results [name='results']
edit/<str:page> [name='edit']
random [name='random']
The current path, { url 'page' entry }, didn't match any of these.
Please, tell me how can I fix this.
index. html:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
{% endblock %}
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:page>", views.viewpage, name="page"),
path("search", views.search, name="search"),
path("create", views.create, name="create"),
path("addentry", views.add_entry, name="add_entry"),
path("nomatches", views.search, name="nomatches"),
path("results", views.search, name="results"),
path("edit/<str:page>", views.edit, name="edit"),
path("random", views.random, name="random")
]
part of views.py:
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
def viewpage(request, page):
content = util.get_entry(page)
return render(request, "encyclopedia/page.html", {
"content": markdown2.markdown(content),
"title":page
})
page.html
{% extends "encyclopedia/layout.html" %}
{% block title %}
{{ title }}
{% endblock %}
{% block body %}
edit
<h1>{{ title }}</h1>
{{ content|safe }}
{% endblock %}
Since the URL for 'page' is 'wiki/<str: page>' you need to define a get_absolute_url method on your class model that contains the object in question, so do add this method in the models.py class that contains page:
def get_absolute_url(self):
return reverse('page',kwargs={str:self.str})
Then, in the template, you can refer to it as
{% object.get_absolute_url%}.
Related
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.
When I use {% url %} method to create link
{% url application_name:staff:url.linkfield %}
it is producing error in the console i.e.
raise TemplateSyntaxError("Could not parse the remainder: '%s' "
django.template.exceptions.TemplateSyntaxError: Could not parse the remainder: ':staff:url.linkfield' from 'application_name:staff:url.linkfield'
This is my url.py
app_name="application_name"
urlpatterns=[
url(r"^staff/",include('application_name.staff_url', namespace='staff')),
url(r"^customer/",include('application_name.customer_url', namespace='customer')),
]
my staff_url.py
from application_name import views
app_name="staff"
urlpatterns=[
url(r"^customers/",views.customers, name='customers'),
url(r"^orders/$", views.orders, name='orders'),
url(r"^payments/$", views.payments, name='payments'),
]
my customer_url.py
from application_name import views
app_name="customer"
urlpatterns=[
url(r"^items/",views.items, name='items'),
url(r"^checkout/$", views.checkout, name='checkout'),
url(r"^make_payment/$", views.make_payment, name='make_payment'),
]
staf url would be staff/orders or staff/payments
customer urls would be customer/items or customer/checkout etc
Please what can i do
Update
{% for url in links %}
{% url.linkfield %}
{%endfor%}
That is what url.linkfield is for
Update to include view
View
staffLink=[
{'linkfield':"customers", 'name':"Customers",'slug':"staff"},
{'linkfield':"orders", 'name':"Orders",'slug':"staff"},
{'linkfield':"payments", 'name':"payments",'slug':"staff"}]
links=staffLink
request.session['links']= links
context_dict = {'links':links}
html template
{% for link in request.session.links %}
<a href="{% url application_name:staff: link.linkfield as the_url %}" class="nav-link">
{% endif %}
so this is your main url:
urlpatterns=[
url(r"^staff/",include('application_name.staff_url', namespace='staff')),
url(r"^customer/",include('application_name.customer_url', namespace='customer')),
]
you do not need an app_name for the main url.
to rewrite:
{% url application_name:staff:url.linkfield %}
would be
{% url 'staff:customers' %} or
{% url 'staff:orders' %} or
{% url 'staff:payments' %}
or the other urls
{% url 'staff:customers' %} or
{% url 'customer:checkout' %} or
{% url 'customer:make_payment' %}
if links is a result of a queryset, and you use it as context,
and linkfield is a field of that model you used to query, then
{% for url in links %}
{{ url.linkfield }}
{%endfor%}
Try please this syntax
{% url 'some-url-name' arg arg2 as the_url %}
I've been having this error for hours and I can't seem to fix it!
URL.PY:
from django.urls import path
from . import views
app_name = "learning_logg"
urlpatterns = [
#Home Page
path('', views.index, name="index"),
]
VIEWS.PY:
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, "index.html")
INDEX.HTML:
{% extends "learning_logs/base.html" %}
{% block content %}
<p> Learning Log </p>
<p> Learning Log helps you keep track of your learning, for any topic you're learning about gay </p>
{% endblock content %}
BASE.HTML:
<p>
<a> href = "{% url "index" %}"> Learning Log</a>
</p>
{% block content%} {% endblock content %}
I'm trying to make base.html the main framework and then putting index.html inside it, does anyone know how to fix the error?
It says the error is in line 2:
1
2 href = "{% url "index" %}"> Learning Log
3
4
5
6 {% block content%} {% endblock content %}
7
As you have specified app_name in your urls.py. You should do the same when referencing the url in the url template tag like {% url 'learning_logg:index' %}.
See the details in the documentation here.
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.
Im pretty new to both python and django , currently reading the Python Crash Course by Eric Matthes . Im trying to code a simple learning log , but im having some issues adding new topics using the django form . Heres the code:
urls.py:
from django.urls import path , re_path
from . import views
urlpatterns = [
#Home page
path('', views.index, name='index'),
path('topics/', views.topics , name='topics'),
re_path(r'^topics/(?P<topic_id>\d+)/$' , views.topic , name = 'topic'),
re_path(r'^new_topic/$' , views.new_topic , name = 'new_topic')
]
app_name = 'learning_logs'
part of view.py:
def new_topic(request):
if request.method != 'POST':
form = TopicForm
else:
form = TopicForm(request.POST)
if form.is_valid():
form.save
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form' : form}
return render(request , 'learning_logs/new_topic.html' , context)
new_topic.html:
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>Added a new topic:</p>
<form action="{% url 'learning_logs:new_topic' %}" method="post">
{% csrf_token %}
{{form.as_p}}
<button name='submit'>add topic</button>
</form>
{% endblock content %}
topics.html:
{% extends 'learning_logs/base.html' %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>{{topic}}</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
Add a new topic:
{% endblock content %}
the brackets are missing. It should form.save() as bkrop mentioned