Django url regular expression matching but page not found error - python

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?

Related

Cannot fix Django NoReverseMatch error despite URL being withing urls.py

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' %}

Django not serving text content (Second attempt)

Summary:
I’m writing a Django web app whose purpose is to showcase a writing sample (a ‘post mortem’) which is basically like a blog post for all intents and purposes. Django is not serving the content and I am not sure why. The problem I figure is with either my views.py or template (copied below). I don’t think the issue is with my models or urls.py but I included them anyways.
Details:
This is my second attempt at getting my Django project to serve this template properly. In my prior first attempt, I encountered a similar issue:
Django not serving text content (First attempt)
There in that question, another SO member answered by identifying three mistakes I was making. The problem there was that I was missing a for loop inside my template, I was missing an all() class method inside my views.py and the context dictionary key value pair in views.py was not pluralized.
Those issues have been resolved however my new issue involves Django serving a blank template when I am expecting the Lorem Ipsum content to show.
Django should be pulling all the class objects from my models.py and then be sending them to the alls/landings.html. I am expecting the title, publication date, image and body content to render on my landing page. But instead, my ‘mortems’ app content (a blog post) isn’t showing on the landing page. The only thing that shows is the heading. To illustrate so you can see what I see, here is what my landing page looks like now:
Based on what you people see below, who can tell me what is wrong with my views / landings.html template?
The full source code can be found on my GitHub page. Here is a snapshot of the state of my project (tagged as v0.6.0).
What follows are the code samples where I suspect my issue exists.
Here is my latest views.py:
from django.shortcuts import redirect, render, get_object_or_404
from mortems.models import Mortem
def mortems(request):
mortems = Mortem.objects.all().order_by('-pub_date')
context = {'mortems':mortems}
return render(request, 'alls/landings.html', context)
Here is my templates/alls/landings.html:
{% load static %}
<html>
<head>
<title> BLOG </title>
<style> </style>
<!-- <link rel="stylesheet" href="{% static 'redactors/style.css' %}"> -->
</head>
<body>
{% block content %}
<h1> BLOG POST:</h1>
{% for mortem in mortems %}
<h1>{{ mortem.title }}</h1>
<h4>Date: {{ mortem.pub_date_preference }}</h4>
<br />
Image: <img src="{{ mortem.image.url }}" class="img-responsive center-block" style="max-height:300px;" />
<br />
<!-- Body text should go here : -->
Body Text:
<p>{{ mortem.body|safe }}</p>
<br />
<br />
{% endfor %}
{% endblock %}
</body>
</html>
Here my project’s main urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('redactors.urls')),
path('', include('counters.urls')),
path('', include('mortems.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Here is my app’s (mortems) urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.mortems, name='mortems'),
]
Here is my app’s models.py:
from django.db import models
import datetime
from django.utils import timezone
from django.utils.deprecation import MiddlewareMixin
# Create your models here.
class Mortem(models.Model):
title = models.CharField(max_length=161)
pub_date = models.DateTimeField()
image = models.ImageField(upload_to='media/')
body = models.TextField()
now = datetime.datetime.now()
def __str__(self):
return self.title
def pub_date_preference(self):
# a = self.pub_date.timezone.now("US")
b = self.pub_date.strftime("%A %d %B %Y # %-I:%M:%S %p")
# c = pytz.timezone("US")
return (b)
def summary(self):
return self.body[:1024]
You are using the same path for views.home in redactors.urls and views.mortems in mortems.urls i.e '/'
CC_Redact_Iter3/urls.py you configured in this order
urlpatterns = [
#Django serves urls in the order you gave
path('admin/', admin.site.urls), #1st
path('', include('redactors.urls')), #2nd
path('', include('counters.urls')), #3rd
path('', include('mortems.urls')), #4th
]
redactors/urls.py
urlpatterns = [
path('', views.home, name='home'), #here you have to change the home path
path('alls/results', views.results, name='results'),
]
mortems/urls.py
urlpatterns = [
path('', views.mortems, name='mortems'), #As you can see views.home is also having same path so change the path for home
]
In your case
def home(request):
if 'ccEntry' in request.GET:
number = request.GET['ccEntry']
redacted_num = 'xxxx xxxx xxxx {}'.format(number[-4:])
return render(request, 'alls/results.html', {'number':number, 'redacted_num':redacted_num})
else:
return render(request, 'alls/landings.html') #this is being rendered instead mortem
Change your CC_Redact_Iter3/urls.py and redactors/urls.py as shown below
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('mortems.urls')),
path('', include('redactors.urls')),
path('', include('counters.urls')),
]
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns = [
path('home/', views.home, name='home'), #here you have to change the home path
path('alls/results', views.results, name='results'),
]
And the date format in you mortems/models.py is Invalid (%-I)
def pub_date_preference(self):
# a = self.pub_date.timezone.now("US")
b= self.pub_date.strftime("%A %d %B %Y # %I:%M:%S %p") #try something like this
# c = pytz.timezone("US")
return (b)
Courtesy of #MeL in the comments, the solution is to include ‘mortems’ as the first argument inside my path() function inside the mortems app’s urls.py. This file looks like this now:
urlpatterns = [
path('mortems', views.mortems, name='mortems'),
]
Now when I navigate to http://127.0.0.1:8000/mortems, the landings.html template renders exactly as intended, with all the content present. To see, here is my mortems page now:
So that is the solution I guess. But I remain flummoxed and curious: why? With the path parameter empty ’’, I’d expect Django to serve the landings.html template on the home page / landing page at this location: http://127.0.0.1:8000/. Django serves the template but all the content is missing. Only after adding a string as an argument the content shows. Why is that?
If someone could kindly answer why, I’d be happy to update this answer here with more information.

Python + Django URL & View errors when attempting to POST to_do item

This is my first attempt at utilizing Django and I've run into an issue with the URL & Views files. I created a project called "reading". Within that project, I created two apps, "products" and "speech". Within the "speech" urls.py file, I have the following code:
from django.urls import path
from speech.views import todoView, addTodo
urlpatterns = [
path('todo/', todoView),
path('addTodo/', addTodo)
]
In the views.py file I have the following code:
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from .models import TodoItem
def todoView(request):
all_todo_items = TodoItem.objects.all()
return render(request, 'todo.html',
{'all_items': all_todo_items})
def addTodo(request):
new_item = TodoItem(content = request.POST['content'])
new_item.save()
return HttpResponseRedirect('/todo/')
In the project folder, within the urls.py file, I have:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('products/', include('products.urls')),
path('speech/', include('speech.urls'))
In the project folder, within the "templates" directory, I have a "todo.html" file with:
<h1>This is the todo page</h1>
<ul>
{% for todo_item in all_items %}
<li>{{ todo_item.content}}</li>
{% endfor %}
</ul>
<form action="/addTodo/" method="POST">{% csrf_token %}
<input type="text" name="content" />
<input type="submit" value="Add" />
</form>
When I attempt to add an item to the todo model, I get this error "The current path, addTodo/, didn't match any of these". I tried prepending "speech" to the form such as:
<form action="speech/addTodo/" method="POST">{% csrf_token %}
however, I now get this error:
The current path, speech/todo/speech/addTodo/, didn't match any of these.
Why is it duplicating the path when I prepend "speech" to the /addTodo action?
Not sure if this is associated to the error, but before I implemented a project level "templates" directory, I gave each app its own "templates" directory. Within those directories, I created an "index.html" file with separate content. When I had an index path for each apps, I couldn't get the apps to render the "index.html" file that was associated to it. Instead, it seemed the second application tried to render the "index.html" file of the first app. Is there a top down rule when it comes to templates in Django?
You missed a slash
Try this:
<form action="/speech/addTodo/" method="POST">{% csrf_token %}
A more 'Django' way of doing this could be:
from django.urls import path
from speech.views import todoView, addTodo
urlpatterns = [
path('todo/', todoView),
path('addTodo/', addTodo, name='add-todo')
]
Then in the template:
<form action="{% url 'add-todo' %}" method="POST">{% csrf_token %}

python - Django : Page Not found

I have looked around and can't really find a solution to my problem. Here is the error django throws. This error is being thrown when on my homepage I have a fiew links that upon clicking should direct you to a details view of said link.
Using the URLconf defined in untitled.urls, Django tried these URL patterns, in this order:
^$
^index/ ^$ [name='index']
^index/ ^(?P<distro_id>[0-9]+)/$ [name='distro_id']
^admin/
The current URL, index//, didn't match any of these.
To my knowledge I don't understand why this error is being thrown.
Here is my urls.py
from django.conf.urls import include, url
from django.contrib import admin
import index.views
urlpatterns = [
url(r'^$', index.views.index),
url(r'^index/', include('index.urls', namespace='index')),
url(r'^admin/', admin.site.urls),
]
My index/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
# /index/
url(r'^$', views.index, name='index'),
#/distro/123/
url(r'^(?P<distro_id>[0-9]+)/$', views.detail, name='distro_id'),
]
My views.py
from django.shortcuts import get_object_or_404, render
from django.template import loader, RequestContext
from django.http import Http404
from .models import Distros
def index(request):
all_distros = Distros.objects.all()
context = {'all_distros': all_distros, }
return render(request, 'index/index.html', context)
def detail(request, distro_id,):
distro_id = get_object_or_404 (Distros, pk=distro_id)
return render(request, 'index/detail.html', {'distro_id': distro_id})
template code:
{% extends 'index/base.html' %}
{% block body %}
<ul>
{% for distro in all_distros %}
<li>{{ index.distro_id }}</li>
{% endfor %}
</ul>
{% endblock %}
I believe those are all the relevent files. I believe everything is setup correctly so I am not sure why the error is being thrown. I'm sure im missing something simple that i'm just overlooking.
Please don't use hardcoded URLs as they are error prone as in your situation. Instead of:
<a href="/index/{{ index.distro.id }}/">
use the url template tag with your namespace (index) and view name (distro_id):
<a href="{% url 'index:distro_id' index.id %}">
Note that you also have an error with index.distro.id as index is actually a Distros object. It has an id field, but not distro.id.

how to send a parameter from html to django view.py

I am a beginner and did a lot of search but every time I got only "django to html" as search result every time. I am following this tutorial:
http://www.djangobook.com/en/2.0/chapter07.html
but on the way I am not able to pass paramter from html to view.py.
Here is my directory:
directory: mysite:
directory: books
directory: templates
search_form.html
<html>
<head>
<title>Search</title>
</head>
<body>
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
views.py
from django.shortcuts import render
from django.http import HttpResponse
def search_form(request):
return render(request, 'books/search_form.html')
def search(request):
if 'q' in request.GET:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.'
return HttpResponse(message)
urls.py for books
from django.conf.urls import url,include
from . import views
urlpatterns = [
url(r'^$',views.search_form,name='search_form'),
url(r'^$', views.search,name='search'),
]
and urls.py in mysite directory
"""mysite URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.9/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Add an import: from blog import urls as blog_urls
2. Import the include() function: from django.conf.urls import url, include
3. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
"""
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^books/', include('books.urls')),
]
Now the problem is when I type: http://127.0.0.1:8000/books/
it successfully shows the form's textbox and submit button but when I press submit it shows me this:
Firstly, you need two different regexes for the search_form and search results. For example:
url(r'^$',views.search_form,name='search_form'),
url(r'^search/$', views.search,name='search'),
Next, you need to update the form's action to point to the search view. Since you have included your books/urls.py with the /books/ prefix, you need:
<form action="/books/search/" method="get">
It is better to use the url tag instead of hardcoding your urls. In this case, you would do:
<form action="{% url 'search' %}" method="get">
In addition to the answer of Alasdair I would use "books:search" for clear namespace:
<form action="{% url 'books:search' %}" method="get">
The url /search/ doesn't exist, you didnt define that it should exist.
It would be /books/ judging from that URLs file you showed. Also on a side note, don't use http://www.djangobook.com/en/2.0/index.html
They have a warning on the main page that it is no longer up to date.
Use masteringdjango.com and other up to date resources.

Categories

Resources