I am trying to complete a CS50 Project, I want to render a HTML page, the template is in respective templates/encyclopedia directory.
The error page for url 127.0.0.1:8000/wiki/HTML says NoReverseMatch at wiki/HTML.
Reverse for 'edit' not found. 'edit' is not a valid view function or pattern name.
The responsible URLS.py are "wiki/<str:search>" and "wiki/random".
I'm sorry but I don't want to post this long code here but I am stuck at this problem for weeks now.
I have tried many ways don't know what's wrong with this code.
The below is my URLS.py, the projects index url includes the below urls:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("wiki/newpage", views.newpage, name="newpage"),
# path("wiki/<str:edit>/edit", views.edit, name="edit"),
path("wiki/random", views.random, name="random"),
path("wiki/<str:search>", views.search, name="search"),
path("wiki/", views.find, name="find")
]
The below is my VIEWS.py:
from django.shortcuts import render, redirect
from django.contrib import messages
import markdown2 as md
from . import util
from django import forms
import re, random as rand
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
def search(request, search):
if search in util.list_entries():
html = md.markdown(util.get_entry(search))
return render(request, "encyclopedia/search.html", {
"search": search, "html": html
})
else:
return render(request, "encyclopedia/error.html")
def random(request):
randomPage = rand.choice(util.list_entries())
if randomPage in util.list_entries():
html = md.markdown(util.get_entry(randomPage))
return render(request, "encyclopedia/search.html", {
"random": randomPage, "html": html
})
else:
return render(request, "encyclopedia/error.html")
def find(request):
if request.method == "GET":
query = request.GET.get('q')
for queryMatch in util.list_entries():
if query.casefold() == queryMatch.casefold():
html = md.markdown(util.get_entry(query))
return render(request, "encyclopedia/search.html", {
"queryMatch": queryMatch, "html": html
})
regex = re.compile(query.casefold())
matchList = []
for a in util.list_entries():
if regex.match(a.casefold()):
matchList.append(a)
if not matchList:
matchList = util.list_entries()
return render(request, "encyclopedia/list.html", {
"match": matchList
})
class NewPageForm(forms.Form):
title = forms.CharField(label="Title")
content = forms.CharField(label="Markdown Content", widget=forms.Textarea(attrs={'cols': '100'}))
def newpage(request):
if request.method == "POST":
form = NewPageForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
if title in util.list_entries():
messages.error(request, f"'{title}' page title already exists!!\nPlease type another title.")
return render(request, "encyclopedia/newpage.html", {
"form": form
})
else:
util.save_entry(title, content)
return redirect(f"/wiki/{title}")
else:
return render(request, "encyclopedia/newpage.html", {
"form": form
})
return render(request, "encyclopedia/newpage.html", {
"form": NewPageForm()
})
# def edit(request, edit):
# entry = util.get_entry(edit)
Have you include your app.urls in project.urls?
Including other URLconfs
Some example from Django tutorial:
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
mysite/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
Related
I'm trying to implement a Sitemap for my app and I get the error
"Reverse for 'index' not found. 'index' is not a valid view function or pattern name."
even though these views are set up.
What could cause this? I have no problem with dynamic sitemaps, just the static one.
My views.py
def front_page(request):
return render(request, 'django_modules_testing_app/front_page.html', {})
def about_us(request):
return render(request, 'ihgr_app/about_us.html', {})
def index(request):
return render(request, 'django_modules_testing_app/index.html', {})
urls.py
from django.urls import path
from . import views
from . import blocks
from django.contrib.sitemaps.views import sitemap
from .sitemaps import DjangoModulesTestingApp
app_name = 'django_modules_testing_app'
sitemaps = {
'main_app':DjangoModulesTestingApp
}
urlpatterns = [
path('', views.front_page, name='front_page'),
path('', views.index, name='index'),
path('', views.about_us, name='about_us'),
path('category_details/<slug:slug>/', blocks.category_details, name='category_details'),
path('search_website/', views.SearchWebsite.as_view(), name='search_website'),
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},name='django.contrib.sitemaps.views.sitemap')
]
sitemaps.py
from django.contrib.sitemaps import Sitemap
from django.urls import reverse
class StaticSitemap(Sitemap):
changefreq = 'weekly'
priority = 0.8
protocol = 'http'
def items(self):
return ['front_page','index','about_us']
def location(self, item):
return reverse(item)
You've to specify your app name inside reverse(...) like this
class StaticSitemap(Sitemap):
changefreq = 'weekly'
priority = 0.8
protocol = 'http'
def items(self):
return ['front_page','index','about_us']
def location(self, item):
return reverse(f"django_modules_testing_app:{item}")
contact/views.py
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
def contactView(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(subject, message, from_email, ['admin#example.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
# return redirect('success')
return redirect('PostList') #another view from another app
return render(request, "contact.html", {'form': form})
# def successView(request):
# return HttpResponse('Success! Thank you for your message.')
contact/urls.py
from django.contrib import admin
from django.urls import path
from .views import contactView
urlpatterns = [
path('contact/', contactView, name='contact'),
# path('success/', successView, name='success'),
]
blog/views.py
from django.views import generic
from .models import Post, PostImage
# Create your views here.
class PostList(generic.ListView):
queryset = Post.objects.filter(status=1).order_by('-created_on')
template_name = 'index.html'
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
# Add in a QuerySet of all the books
# context['image_list'] = PostImage.objects.all()
# context['image_list'] = self.get_object().postimage_set.all()
context['image_list'] = PostImage.objects.filter(post__slug=self.kwargs.get('slug'))
return context
blog/urls.py
from . import views
from django.urls import path
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]
I need the following in the SIMPLEST DRY manner possible; how do I write this redirect inside contact/views.py?
return redirect('PostList') #another view from another app
PostList is a class-based view from another app called blog. It is the homepage essentially.
for reference..
https://ordinarycoders.com/blog/article/django-messages-framework
In your project folder (eg, my_project/my_project) you should have a urls.py with something like this
path("admin/", admin.site.urls),
path("", include("blog.urls")),
path("", include("contact.urls"))
This allows django to look through all url files in the order listed. So long as all your url names and patterns are unique, then your view should be able to simply do
from django.shortcuts import redirect
from django.urls import reverse
return redirect(reverse('home'))
'home' being the name value of the ListView.
(NB: if you have various applevel urls.py files with path(''... django will take the first one it hits)
having trouble with this tutorial. in my views.py I have this function for login, in views.py:
def login_view(request, *args, **kwargs):
form = AuthenticationForm(request, data=request.POST or None)
if form.is_valid():
user_ = form.get_user()
login(request, user_)
**return redirect("/")**
context = {
"form": form,
"btn_label": "Login",
"title": "Login"
}
return render(request, "accounts/auth.html", context)
however when i try to change the redirect , i only get errors, what should I put in the redirect? i've tried everything like
return redirect("/tweets/list.html")
and
return redirect("public/index.html")
both are locations of file names in the templates folder. I am getting the error, "Page not found (404)". The only address that did redirect was when I put https://www.google.com/
in accounts/views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
# Create your views here.
# Function based views to Class Based Views
def login_view(request, *args, **kwargs):
form = AuthenticationForm(request, data=request.POST or None)
if form.is_valid():
user_ = form.get_user()
login(request, user_)
return redirect('')
context = {
"form": form,
"btn_label": "Login",
"title": "Login"
}
return render(request, "accounts/auth.html", context)
def logout_view(request, *args, **kwargs):
if request.method == "POST":
logout(request)
return redirect("/login")
context = {
"form": None,
"description": "Are you sure you want to logout?",
"btn_label": "Click to Confirm",
"title": "Logout"
}
return render(request, "accounts/auth.html", context)
def register_view(request, *args, **kwargs):
form = UserCreationForm(request.POST or None)
if form.is_valid():
user = form.save(commit=True)
user.set_password(form.cleaned_data.get("password1"))
# send a confirmation email to verify their account
login(request, user)
return redirect("/")
context = {
"form": form,
"btn_label": "Register",
"title": "Register"
}
return render(request, "accounts/auth.html", context)
here is urls.py:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, re_path, include # url()
from django.views.generic import TemplateView
from accounts.views import (
login_view,
logout_view,
register_view,
)
from tweets.views import (
home_view,
tweets_list_view,
tweets_detail_view,
)
urlpatterns = [
path('', home_view),
path('admin/', admin.site.urls),
path('global/', tweets_list_view),
path('login/', login_view),
path('logout/', logout_view),
path('register/', register_view),
path('<int:tweet_id>', tweets_detail_view),
re_path(r'profiles?/', include('profiles.urls')),
path('api/tweets/', include('tweets.api.urls')),
re_path(r'api/profiles?/', include('profiles.api.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
thnx
Redirect should take a valid path to an url defined in urls.Py, not a file in templates/some/urls.html.
I would suggest not to used "hard coded urls" though, but instead using the view name and parameters such as return redirect('some-view-name', foo='bar')
i solved the error by looking at urls.py, looking into url patterns, picking
path('global/', tweets_list_view),
and dropping '/global/' into return redirect("/") so that line looks like:
return redirect("/global/")
so the error is Page not found(404) when I am requesting the instance that does not exist. I would like to customize the 404 page, instead of displaying the general error.
Here is my new_wiki/urls
from django.urls import path
from . import views
from .views import IndexView, InstanceView, AddPostView, EditPost
urlpatterns = [
# path('', views.index, name="index")
path('', IndexView.as_view(), name="index"),
path('instance/<int:pk>', InstanceView.as_view(), name="instance"),
path('create_post/', AddPostView.as_view(), name="create_post"),
path('instance/edit/<int:pk>', EditPost.as_view(), name="edit_post")
]
And my InstanceView class
class InstanceView(DetailView):
model = Post
template_name = 'new_wiki/instance.html'
I have tried to use the solution from Django documentation:
def detail(request, post_id):
try:
p = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
raise Http404("Poll does not exist")
return render(request, 'new_wiki/instance.html', {'post': p})
but it is still returning the same 404 page. Thank you
You can just render a page with a 404 status:
def detail(request, post_id):
try:
p = Post.objects.get(pk=post_id)
except Post.DoesNotExist:
return render(request, 'new_wiki/404error.html', status=404)
return render(request, 'new_wiki/instance.html', {'post': p})
If you want to specify a custom 404 page in general, you specify the handler404 [Django-doc] in the urls.py:
from django.urls import path
from . import views
from .views import IndexView, InstanceView, AddPostView, EditPost
urlpatterns = [
# path('', views.index, name="index")
path('', IndexView.as_view(), name="index"),
path('instance/<int:pk>', InstanceView.as_view(), name="instance"),
path('create_post/', AddPostView.as_view(), name="create_post"),
path('instance/edit/<int:pk>', EditPost.as_view(), name="edit_post")
]
handler404 = views.handler404
In the view you can then analyze the exception parameter and return a specific
# app/views.py
from django.http import HttpResponseNotFound
def handler404(request, exception):
data = exception.args
if data:
return HttpResponseNotFound(data[0])
return HttpResponseNotFound('some text')
This then works if you set the DEBUG setting [Django-doc] to False:
# settings.py
DEBUG = False
In that case the handler will be invoked when you raise a Http404.
Please use get_object_or_404 method
from django.shortcuts import get_object_or_404
def detail(request, post_id):
p = get_object_or_404(Post,pk=post_id)
return render(request, 'new_wiki/instance.html', {'post': p})
Please check this is working.
I don't know why I am getting this issue with my code. I've tried a bunch of stuff to resolve it but I can't
NoReverseMatch at /property/
Reverse for 'property_detail' not found. 'property_detail' is not a valid view function or pattern name.
Request Method:GETRequest URL:http://127.0.0.1:8000/property/Django Version:3.0.5Exception Type:NoReverseMatchException Value:
Reverse for 'property_detail' not found. 'property_detail' is not a valid view function or pattern name.
Exception Location:E:\django_projects\env\lib\site-packages\django\urls\resolvers.py in _reverse_with_prefix, line 677Python Executable:E:\django_projects\env\Scripts\python.exePython Version:3.7.4Python Path:
['E:\\django_projects\\hotel\\src\\project',
'E:\\django_projects\\env\\Scripts\\python37.zip',
'c:\\users\\user\\appdata\\local\\programs\\python\\python37\\DLLs',
'c:\\users\\user\\appdata\\local\\programs\\python\\python37\\lib',
'c:\\users\\user\\appdata\\local\\programs\\python\\python37',
'E:\\django_projects\\env',
'E:\\django_projects\\env\\lib\\site-packages']
html code
<ul class="probootstrap-main-nav">
<li class="active">Home</li>
<li>Properties</li>
<li>Agents</li>
<li>About</li>
<li>Contact</li>
</ul>
project/urls (project directory)
urlpatterns = [
path('admin/', admin.site.urls),
path('property/', include('property.urls', namespace='property')),
path('agents/', include('agents.urls', namespace='agents')),
path('about/', include('about.urls', namespace='about')),
path('contact/', include('contact.urls', namespace='contact')),
]
propert/urls (app)
from django.urls import path
from . import views
app_name= 'property'
urlpatterns = [
path('', views.property_list, name='property_list'),
path('<int:id>', views.property_detail, name='property_detail'),
]
property/views
from django.shortcuts import render
from .models import (Property, Category)
from .forms import ReserveForm
def property_list(request):
property_list = Property.objects.all()
template = 'list.html'
context = {
'property_list': property_list,
}
return render(request, template, context)
def property_detail(request, id):
property_detail = Property.objects.get(id=id)
if request.method == 'POST':
reserve_form = ReserveForm(request.POST)
if reserve_form.is_valid():
reserve_form.save()
else:
reserve_form = ReserveForm()
return render(request, 'detail.html', {
'property_detail': property_detail,
'reserve_form': reserve_form
})