I have created a Django project foo.
├── manage.py
└── foo
├── __init__.py
├── settings.py
├── templates
│ ├── xyz.html
│ └── abc.html
├── tests.py
├── urls.py
├── views.py
└── wsgi.py
In views.py , I have created two class based view HomePage and ListPage
And routing configuration defined like this in urls.py:
urlpatterns = patterns('',
url(r'^$', HomePage.as_view() , name='home'),
url(r'^list$', ListPage.as_view(), name='list'),
# url(r'^admin/', include(admin.site.urls)),
)
Throws Error:
(InteractiveConsole)
>>> import django
>>> django.setup()
>>> from django.core.urlresolvers import resolve
>>> resolve('/')
ResolverMatch(func=<function HomePage at 0x7f77769bb9d8>, args=(), kwargs={}, url_name='home', app_name='None', namespace='')
>>> resolve('list')
Traceback (most recent call last):
File "<console>", line 1, in <module>
...
raise Resolver404({'path': path})
django.core.urlresolvers.Resolver404: {'path': 'list'}
What's going wrong here? Default root url '/' is resolving but 'list' is not resolving
This was a silly mistake of mine :). Though It might be helpful to somebody.
try
>>resolve('/list')
Related
Wup, I'm trying to deploy a localhost web using Django but I get the following error:
TemplateDoesNotExist at /
templates/index.html
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 4.1.2
Exception Type: TemplateDoesNotExist
I was looking tutorials and docs but I didn't found the answer.
Here is my settings.py
ALLOWED_HOSTS = ['*']
DEBUG = True
ROOT_URLCONF = 'FortyTwop.urls'
SECRET_KEY = 'This is a secret key'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ["templates"],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
also urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
]
And views.py
from email import message
from http.client import HTTPResponse
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, 'index.html')
My path tree:
.
├── FortyTwop
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ └── index.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── manage.py
What Im doing bad or what I didn't have in the settings?, this project is just for test.
templates/ is the base path you've configured in the settings, so you'll want
def index(request):
return render(request, 'index.html')
Furthermore, TEMPLATE_DIRS hasn't been a thing since Django 1.8 or so, and you're on Django 4.x. See these instructions.
I was just checking out django, and was trying a view to list the books by passing id as an argument to the URL books/urls.py. But getting 404 page not found error. I'm not getting whats wrong in the url when I typed this url in the browser:
http://192.168.0.106:8000/books/list/21/
bookstore/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('books/', include("books.urls"))
]
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'books'
]
...
...
...
ROOT_URLCONF = 'bookstore.urls'
books/urls.py
urlpatterns = [
path('home/', create),
path('list/(?P<id>\d+)', list_view),
]
books/views.py
def create(request):
form = CreateForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, "Book Created")
return redirect('/books/list', kwargs={"id":instance.id})
return render(request, "home.html", {"form":form})
def list_view(request, id=None):
books = Book.objects.filter(id=id)
return render(request, "list.html", {"books": books})
Project Structure:
├── books
│ ├── admin.py
│ ├── forms.py
│ ├── __init__.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
├── bookstore
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
Here is the screenshot -
EDIT - As addressed in the comments - Tried by appending / in the url expression of thebooks.urls but no luck :(
You are using the new path from Django 2.0 incorrectly. You shouldn't use a regex like \d+. Try changing it to:
path('list/<int:id>/', list_view, name='list_view'),
The name is required if you want to reverse the URL.
If you want to stick with regexes, then use re_path (or url() still works if you want to be compatible with older versions of Django). See the URL dispatcher docs for more info.
Note the trailing slash as well - otherwise your path matches http://192.168.0.106:8000/books/list/21 but not http://192.168.0.106:8000/books/list/21/.
I'm trying to code an e-phrasebook with Django to help people learn languages. Or actually a new version of an older one with new features. Anyway I'm badly stuck on the first meters here.
I have added some objects to the database and want to show them at the "categories" url. The first url http://127.0.0.1:8000/ works nicely and gives me a wonderful hello world. However, I need to connect the new app to the project, and when I try to open the url of the app http://127.0.0.1:8000/categories/, the browsers gives me this:
TypeError at /categories/
sequence item 0: expected str instance, Category found
My console complains about app's view.py, and within that about line 9 output = ', '.join(categories). I can't find anything wrong with it. Here is the whole views.py:
from django.http import HttpResponse
from django.shortcuts import render
from .models import Category
def category_list(request):
categories = Category.objects.all()
output = ', '.join(categories)
return HttpResponse(output)
This is the app's url.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.category_list),
]
Here is the main url.py:
from django.conf.urls import url, include
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^categories/', include('phrasebooktwo.urls')),
url(r'^admin/', admin.site.urls),
url(r'^$', views.hello_world),
]
Here is the project tree:
bigboy_phrasebook
├── bigboy_phrasebook
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-35.pyc
│ │ ├── settings.cpython-35.pyc
│ │ ├── urls.cpython-35.pyc
│ │ ├── views.cpython-35.pyc
│ │ └── wsgi.cpython-35.pyc
│ ├── settings.py
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
├── db.sqlite3
├── manage.py
└── phrasebooktwo
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-35.pyc
│ ├── admin.cpython-35.pyc
│ ├── models.cpython-35.pyc
│ ├── urls.cpython-35.pyc
│ └── views.cpython-35.pyc
├── admin.py
├── apps.py
├── migrations
│ ├── 0001_initial.py
│ ├── __init__.py
│ └── __pycache__
│ ├── 0001_initial.cpython-35.pyc
│ └── __init__.cpython-35.pyc
├── models.py
├── tests.py
├── urls.py
└── views.py
How do I get my categories page working? Thanks in advance for your help.
You have to use the str() or repr() or any other method which returns a string on the categories object before you use join(). Let me explain this by taking simple example:
class Category:
def __init__(self, name):
self.name = name
items = [Category('jam')]
out = ', '.join(items)
print(out)
If you run this code, you will get "TypeError: sequence item 0: expected str instance, Category found"
So, you have to modify the code as below:
class Category:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
items = [Category('jam').__str__()]
out = ', '.join(items)
print(out)
def category_list(request):
categories = Category.objects.all()
output = ', '.join(categories)
return HttpResponse(output)
Here categories is queryset object So when you add this join method it iterate as single instance from queryset and instance is objects of Model.So that will not work concat with join method. Use str method in join method like below way
def category_list(request):
categories = Category.objects.all()
output = ', '.join(str(categories))
return HttpResponse(output)
Ah, silly me. I was doing this based on a tutorial at www.teamtreehouse.com and I was sure that I had watched the whole video "First App View" but I had not. Sorry for the trouble people, and thanks for your help anyway! The teacher had intentionally written code that didn't work first, and then explained the right way to do it with this code, that in my own app looks like this:
def category_list(request):
categories = Category.objects.all()
output = ', '.join([str(category) for category in categories])
return HttpResponse(output)
Now it works. I have to remember to finish watching these videos in the future.
I'm trying to customize the 404 error pages in my application. After searching many possible solutions, I created an 404.html template, added a method which should handle HTTP Error 404 and edited my urls.py.
But I guess I'm doing something really wrong. My log presents an invalid syntax error and I cannot solve it.
My views.py:
# HTTP Error 400
def page_not_found(request):
response = render_to_response('404.html',context_instance=RequestContext(request))
response.status_code = 404
return response
And the syntax error:
Traceback (most recent call last):
File "/.../myenv/lib/python3.4/site-packages/django/core/urlresolvers.py", line 393, in urlconf_module
return self._urlconf_module
AttributeError: 'RegexURLResolver' object has no attribute '_urlconf_module'
...
File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
File "/home/dcaled/work/portal-interface/portal/urls.py", line 12
handler404 = 'views.handler404'
^
SyntaxError: invalid syntax
Does anyone have an idea of what's going on?
Thanks.
UPDATE:
After #Alasdair suggestion, I made some changes and fixes. The error has stopped.
Now, my urls.py is like:
handler404 = 'views.page_not_found'
urlpatterns = [
url(r'^$', views.home),]
But I still don't get my custom 404.html when accessing a non existing page.
Instead, a default page is loaded, with this message:
"Not Found
The requested URL /url/404 not found on this server."
Also, my settings.py:
DEBUG = False
ALLOWED_HOSTS = ['*']
TEMPLATE_DIRS = (os.path.join(BASE_DIR , 'portal/templates'),)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
My project tree:
├── fb_dev
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
│
└── portal
├── admin.py
├── forms.py
├── json
├── migrations
├── models.py
├── static
├── templates
│ ├── 404.html
│ └── portal
│ ├── base.html
│ ├── home.html
├── templatetags
├── urls.py
└── views.py
After some months, I revisited the problem and identified a solution. Here is the answer:
a) I removed page_not_found method from the views.py. There's no need to add it. Django automatically gets and renders the 404.html template.
b) Once again, there's no need to edit urls.py. So I removed this line:
handler404 = 'views.page_not_found'
c) Also, it is necessary to edit settings.py, setting DEBUG to FALSE.
DEBUG = False
And I removed the following line:
TEMPLATE_DIRS = (os.path.join(BASE_DIR , 'portal/templates'),)
d) Finally, I created a 404.html template in my portal/templates directory. It is worth noticing that the custom template was rendered only when placed inside this directory.
After some troubles, the revy solution worked perfectly. So, just to clarify:
The Two things to do are:
Add a 404.html file in your_app/template/404.html
Set your DEBUG value to False
After that, Django will render automatically your template.
The handler404 should be outside urlpatterns. If the view is called page_not_found, then it should refer to page_not_found, not handler404.
handler404 = 'views.page_not_found'
urlpatterns = [
url(r'^$', views.home),
]
However, in your case, you do not need a custom 404 handler at all. Remove the handler404 line completely, and the default page_not_found view will render your 404.html template.
I am trying to print a response from the view.. but django shows the page not found error(404)
My main project.urls are:-
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
from . import views
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'ultimatefinalblog.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^$',views.siteindex,name="siteindex"),
url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^markdown/', include('django_markdown.urls')),
)
my blog's urls.py are:-
from django.conf.urls import patterns, url
from blog import views
urlpatterns = patterns('',
#url(r'^$', views.BlogIndex.as_view(), name="index"),
#url(r'^(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
#url(r'^$', views.testview, name="testview"),
url(r'^$', views.index, name="index"),
url(r'^(?P<slug>\S+)$', views.detail, name="entry_detail"),
url(r'^testingpage/', views.testview, name='testview'),
)
I have defined the testview function in my views.py
def testview(request):
return HttpResponse("testing our view!")
When i try to run the url 127.0.0.1:8000/blog/testingpage in my development server it shows the page not found error...can somebody help me solve this problem?
Here is your issue:
In your URL patterns,
url(r'^(?P<slug>\S+)$', views.detail, name="entry_detail"),
url(r'^testingpage/', views.testview, name='testview'),
The testingpage is being matched with ?P<slug>\S+ (for views.detail), before views.testview, and you probably have a raise 404 or something similar line of code to match slug.
So, Change the order:
url(r'^testingpage/', views.testview, name='testview'),
url(r'^(?P<slug>\S+)$', views.detail, name="entry_detail"),
And it should work for you.
Also, Slug is generally matched with (?P<slug>[\w-]+) and not \S+
So!
I succeded to make your code work.
I'll organize this answer in three parts (beware : It will be exhaustive!) :
First :
I'll copy the code I made (almost the same as yours, plus the parts you didn't provide and I had to recode - these are very basic, just to fill the missing parts). I hope it will help you to find how to fix your problem by comparing. I'll also give an hypothesis about your problem.
Second :
I'll talk about your code. There are good habits that could help you to build your django projects (but you don't seem to use these). Please note that your code can work without using these. But it may be more difficult without these habits.
Third :
I will suggest a corrected version of your code with comments to illustrate the second part.
First - The code that works on my computer :
I make my own version of your project with django 1.7.5.
I organized the project like this :
.
├── blog
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── main
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── views.py
│ └── wsgi.py
└── manage.py
Where "main" is the project name and "blog" an app.
From a fresh project, the files I had to modify/add are :
blog/urls.py :
from django.conf.urls import patterns, url
from blog import views
urlpatterns = patterns('',
#url(r'^$', views.BlogIndex.as_view(), name="index"),
#url(r'^(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
#url(r'^$', views.testview, name="testview"),
url(r'^$', views.index, name="index"),
url(r'^(?P<slug>\S+)$', views.detail, name="entry_detail"),
url(r'^testingpage/', views.testview, name='testview'),
)
blog/views.py :
from django.shortcuts import render, HttpResponse
# Create your views here.
def testview(request):
return HttpResponse("testing our view!")
def index(request):
return HttpResponse("Index.")
def detail(request, slug="test"):
return HttpResponse("Detail : " + slug)
main/urls.py :
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
from . import views
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'main.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^$',views.siteindex,name="siteindex"),
url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^markdown/', include('django_markdown.urls')),
)
main/views.py :
from django.shortcuts import render, HttpResponse
# Create your views here.
def siteindex(request):
return HttpResponse("site index!")
Then I just do :
>>>python manage.py migrate
>>>python manage.py runserver
And I can access to http://127.0.0.1:8000/blog/testingpage/ and to other pages. I have no problem this way.
But I you do so, you will see that this URL matches with the r'^(?P<slug>\S+)$' pattern. And therefore /blog/testingpage does not trigger the view testview but the view detail.
So I think your problem may come from the detail view, could you add it to your question to check?
Second - How you could improve your code :
apps and views imports
The way you imports your views is functionnal, but it could be impractible
You could add the app ("blog") containing your views to INSTALLED_APPS in your main/settings.py. And you will be able to use your views just by entering their names as strings.
edit :
This changed with the 1.8 release, now it's recommended to do like you did. My bad.
Your project isn't an app.
Your /main/urls.py suggests that you've a views.py in your /main directory.
Using this directory this way isn't explicitly forbidden, but it's an app's purpose. the /main directory is meant to contain general settings.
I think you should make a second app for your views.py (and probably some url patterns) if you don't want to insert it in the "blog" app.
urlpatterns order
With your blog/urls.py file, your app will "works". But /blog/testingpage/ will trigger the detail view and not the testview view, I'm not sure that is what you want to do. Beware the patterns order!
Third - An other way to do this :
Here is my version of the code.
I have organized the project like this :
.
├── blog
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── main
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── website
├── __init__.py
├── admin.py
├── models.py
├── tests.py
├── urls.py
└── views.py
The new files are :
blog/urls.py
from django.conf.urls import patterns, url
# You don't need this anymore
# from blog import views
urlpatterns = patterns('blog.views', # this first argument will be used as a prefix to locate your views.
url(r'^$', 'index' , name="index"),
# beware the order!
# url(r'^(?P<slug>\S+)$', views.detail, name="entry_detail"),
url(r'^testingpage/', 'testview', name='testview'),
url(r'^(?P<slug>\S+)$', 'detail', name="entry_detail"),
)
blog/views.py
from django.shortcuts import render, HttpResponse
# Create your views here.
def testview(request):
return HttpResponse("testing our view!")
def index(request):
return HttpResponse("Index.")
def detail(request, slug="test"):
return HttpResponse("Detail : " + slug)
INSTALLED_APP in main/settings.py (/!\ Important /!\)
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
'website',
)
main/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'main.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^blog/', include('blog.urls')),
url(r'^markdown/', include('django_markdown.urls')),
url(r'^$', include('website.urls')),
)
website/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
# If you add the app name to INSTALLED_APP you don't need this anymore.
# from . import views
urlpatterns = patterns('website.views', # This first argument will be used as a prefix to locate your views.
url(r'^$', 'siteindex', name="siteindex"),
)
website/views.py
from django.shortcuts import render, HttpResponse
# Create your views here.
def siteindex(request):
return HttpResponse("site index!")
I hope all of this will help.