So I am just starting out on learning Django, and I'm attempting to complete one of the sample applications from the book. I'm getting stuck now on creating DRY URL's. More specifically, I cannot get my context processor to work. I create my context processor as so:
from django.conf import settings
#from mysite.settings import ROOT_URL
def root_url_processor(request):
return {'ROOT_URL': settings.ROOT_URL}
and I placed this file in my app, specifically, mysite/photogallery/context_processors.py . My settings.py file in the root of my project contains:
TEMPLATE_CONTEXT_PROCESSORS = ('mysite.context_processors',)
When I try to go to the ROOT_URL that I've also specified in my settings.py, I receive this error:
TypeError at /gallery/
'module' object is not callable
/gallery/ is the ROOT_URL of this particular application. I realize that perhpas this could mean a naming conflict, but I cannot find one. Furthermore, when I comment out the TEMPLATE_CONTEXT_PROCESSORS definition from settings.py, the application actually does load, however my thumbnail images do not appear (probably because my templates do not know about ROOT_URL, right?). Anyone have any ideas as to what the problem could be?
EDIT: Here's some information about my settings.py in case it is of use:
ROOT_URLCONF = 'mysite.urls'
ROOT_URL = '/gallery/'
LOGIN_URL = ROOT_URL + 'login/'
MEDIA_URL = ROOT_URL + 'media/'
ADMIN_MEDIA_PREFIX = MEDIA_URL + 'admin/'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
TEMPLATE_CONTEXT_PROCESSORS = ('mysite.photogallery.context_processors',)
EDIT2: I'm going to add some information about my url files. Essentially I have a root urls.py, a real_urls.py which is also located at the root, and a urls.py that exists in the application. Basically, root/urls.py hides ROOT_URL from real_urls.py, which then includes my app's urls.py.
root/urls.py:
from django.conf.urls.defaults import *
#from mysite.settings import ROOT_URL
from django.conf import settings
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Example:
(r'^blog/', include('mysite.blog.urls')),
url(r'^%s' % settings.ROOT_URL[1:], include('mysite.real_urls')),
)
root/real_urls.py:
from django.conf.urls.defaults import *
from django.contrib import admin
urlpatterns = patterns('', url(r'^admin/(.*)', admin.site.root),
url(r'^', include('mysite.photogallery.urls')),
)
root/photogallery/urls.py (note that this one probably is not causing any of the problems, but I'm adding it here in case anyone wants to see it.):
from django.conf.urls.defaults import *
from mysite.photogallery.models import Item, Photo
urlpatterns = patterns('django.views.generic', url(r'^$', 'simple.direct_to_template', kwargs={'template': 'index.html', 'extra_context': {'item_list': lambda: Item.objects.all()}
},
name='index'), url(r'^items/$', 'list_detail.object_list', kwargs={'queryset': Item.objects.all(), 'template_name': 'items_list.html', 'allow_empty': True },
name='item_list'), url(r'^items/(?P<object_id>\d+)/$', 'list_detail.object_detail', kwargs={'queryset': Item.objects.all(), 'template_name': 'items_detail.html' }, name='item_detail' ), url(r'^photos/(?P<object_id>\d+)/$', 'list_detail.object_detail', kwargs={'queryset': Photo.objects.all(), 'template_name': 'photos_detail.html' }, name='photo_detail'),)
TEMPLATE_CONTEXT_PROCESSORS should contain a list of callable objects, not modules. List the actual functions that will transform the template contexts. Link to docs.
Related
My Django site isn't working properly. It's hard to explain but when I run my Django web server and go to http://127.0.0.1:8000/hello/ I see "Hello, World!" as expected. But when I go to http://127.0.0.1:8000/dashboard/ I see the same thing, when I should be seeing "Hello". There is to much code to put on stack overflow and it won't make sense so I made a GitHub repo https://github.com/Unidentified539/stackoverflow.
So to simplify your life
urlpatterns = [
path("",views.pomo,name="pomo"),
path("agenda/",views.agenda,name="agenda"),
path("notes/",views.notes,name="notes"),
]
this is your urls.py file in you app
just type this in your project urls.py so you don’t make a mess with paths and includes
urlpatterns = [
path('admin/', admin.site.urls),
path("",include('pomofocus.urls'))
]
this is just an example you need to enter your own paths and views
What's your code problem?
According to your code, you have two same paths for the home page, and when you enter http://127.0.0.1:8000/hello/ Django look at the project-level urls.py (in your code djangoProject1/urls.py) and knows that must go in app-level urls.py (in your code practice/urls.py) and in this file, you have two same paths, and Django uses the first one so you get write page because first one is related to hello view and when you type http://127.0.0.1:8000/dashboard/ Django again look at the project-level urls.py and knows that must go in app-level urls.py and in this file again use the first path and you get incorrect HTML file (because both paths are the same and Django always use the first one)
How to fix this?
in project-level url.py set both paths to '' and in app-level set your project-level paths. (in other words, replace paths in app-level and project-level
djangoProject1/urls.py:
import practice.urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('practice.urls')),
]
practice/urls.py:
from django.urls import path
from practice import views
urlpatterns = [
path('hello/', views.hello_world, name='hello_world'),
path('dashboard/', views.dashboard, name='dashboard')
]
Your code should be like in
practice/urls.py
from django.urls import path
from practice import views
urlpatterns = [
path(" ", views.hello_world, name='hello_world'),
path("dashboard", views.dashboard, name='dashboard')
]
Project1 urls.py
import practice.urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path(" ", include('practice.urls')),
]
Say I am creating a Todo app in Django, traditionally I would include a path to my app in the base_project urls.py file. However, today I came across a tutorial where they used a router for this same purpose I've already stated.
Why would I want to use a Router instead of including the path in my urls.py file?
For reference, here is a snip from the tutorial found at https://www.digitalocean.com/community/tutorials/build-a-to-do-application-using-django-and-react
# backend/urls.py
from django.contrib import admin
from django.urls import path, include # add this
from rest_framework import routers # add this
from todo import views # add this
router = routers.DefaultRouter() # add this
router.register(r'todos', views.TodoView, 'todo') # add this
urlpatterns = [
path('admin/', admin.site.urls), path('api/', include(router.urls)) # add this
]
Here backend is the main django project name.
Both works the same. You can add url in the urlpatterns. I had the same situation as yours where in a tutorial they were using routing instead of url patteren but i studied and both works the same.
In Django 1.7.x this construct was working:
# urls.py
import views
urlpatterns = ('',
url(r'^$', views.index)
)
In Django 1.8.X it stopped working. Now I get this error message when I run the default Django server:
No module named 'views'
I also tried this:
from system.views import *
urlpatterns = ('',
url(r'^$', views.index)
)
This results in:
name 'views' is not defined
And this:
from system import views
urlpatterns = ('',
url(r'^$', views.index)
)
I also tried many more combinations that I've seen at stackoverflow, but none of them works. Hope someone can share what magic combination should do the trick.
EDIT
\home
\jacobian
\apps
\apps
__init__.py
settings.py
urls.py
views.py
...
\system
__init__.py
urls.py
views.py
...
I just tried to recreate this issue. It seems that you are correct and just import views no longer works. However, the following import statement works fine for me:
from . import views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', views.index)
]
You can see an example here on the django documentation. I also think this related Stack Overflow question can clarify they reason for dot import syntax:
Q: Python "from [dot]package import ..." syntax
You should include the views.py file from the application that you have created. So try
from <your app name>.views import *
Your statement is a bit of a mix.
Before version 1.8 it was
from myapp import views
urlpatterns = patterns('',
url('^$', views.myview),
url('^other/$', views.otherview),
)
Now, from version 1.8, there is no need for the first void argument to patterns when assigning urlpatterns. Actually there is no need to call patterns at all.
Here is one example form my latest project with Django 1.8:
urlpatterns = [
url(r'^$', HomePage.as_view(), name='home'),
url(r'^play/', include('play.urls', namespace='play', app_name='play')),
]
And as described in the Django 1.8 release docs:
Thus patterns() serves little purpose and is a burden when teaching
new users (answering the newbie’s question “why do I need this empty
string as the first argument to patterns()?”). For these reasons, we
are deprecating it. Updating your code is as simple as ensuring that
urlpatterns is a list of django.conf.urls.url() instances.
For example:
from django.conf.urls import url
from myapp import views
urlpatterns = [
url('^$', views.myview),
url('^other/$', views.otherview),
]
I have a JS module (a bunch of interface code). Let's call it mymodule. It is located at myapp/modules/mymodule. I want to keep together urls.py and views.py associated with this module. In other words I want to somehow reference myapp/modules/mymodule/urls.py from my root myapp/urls.py and not to cram my root myapp/views.py with all those handlers associated with mymodule. So, this is what I tried by now:
## myapp/urls.py
from django.conf.urls import url
from myapp import views
urlpatters = [
url(r'^$', views.index, name = 'index'),
... a lot of other urls
... and now I want to include urls associated with mymodule
url(r'^mymodule/',include('myapp.modules.mymodule.urls'))
]
## myapp/modules/mymodule/urls.py
from myapp.modules.mymodule import handlers
urlpatters = [
url(r'^dosomething/',handlers.dosomething)
]
## myapp/modules/mymodule/handlers.py
from django.http import HttpResponse
def dosomething(request):
return HttpResponse("Hello world!")
And I want this - when a user goes to 127.0.0.1:8000/myapp/mymodule/dosomething, he or she should see "Hello world!" message.
EDIT
My updated version of the code which still leads to Page not found error looks like this:
## myapp/urls.py
from django.conf.urls import *
from myapp import views
urlpatterns = patterns('',
url(r'^$',views.index, name='index'),
... a lot of other working urls
url(r'^myapp/mymodule',include('myapp.modules.mymodule.urls')),
)
## myapp/modules/mymodule/urls.py
from django.conf.urls import *
from myapp.modules.mymodule import handlers
urlpatterns = patterns('',
url(r'^dosomething/',handlers.dosomething),
)
## myapp/modules/mymodule/handlers.py
from django.http import HttpResponse
def dosomething(request):
return HttpResponse("Hello world!")
EDIT
My root urls.py file now looks like this:
## myapp/urls.py
from django.conf.urls import *
from myapp import views
urlpatterns = patterns('',
url(r'^$',views.index, name='index'),
... a lot of other working urls
url(r'^myapp/mymodule/',include('myapp.modules.mymodule.urls')),
)
So, there is an ending slash now, but the problem is - when I go to 127.0.0.1:8000/myapp/mymodule/dosomething, the Django debugger says that Page not found and that it tried just ^myapp/ ^myapp/mymodule/ pattern - so I see no mentioning of ^dosomething/ pattern. However, if I now go to 127.0.0.1:8000/myapp/myapp/mymodule/dosomething, I now see in the debugger page that it tried ^myapp/ ^myapp/mymodule/ /dosomething pattern. It says /dosomething, because I played with mymodule/urls.py and now it looks like:
## myapp/modules/mymodule/urls.py
from django.conf.urls import *
from myapp.modules.mymodule import handlers
urlpatterns = patterns('',
url(r'/dosomething',handlers.dosomething),
)
So, I guess the reason of all these troubles is that I can't combine all these patterns together to make them work. I need clear understanding on how my url pattern should look like inside root urls.py and inside myapp/urls.py
Add the myapp prefix to the url regex:
url(r'^myapp/mymodule/',include('myapp.modules.mymodule.urls'))
Also note that urlpatters should be created by the patterns() function:
from django.conf.urls import patterns
urlpatterns = patterns('',
...
)
UPDATE: Sorry, I didn't notice that first urls.py is from the app. I confused it with the project urls.py. So as I understand now you should have three urls.py:
project/urls.py
urlpatterns = patterns('',
url(r'^myapp/',include('myapp.urls')),
)
myapp/urls.py
urlpatterns = patterns('',
url(r'^mymodule/',include('myapp.modules.mymodule.urls')),
)
myapp/modules/mymodule/urls.py
urlpatterns = patterns('',
url(r'dosomething/', handlers.dosomething),
)
I'm having some weird issues with class-based-views and reverse_lazy.
Following error shows up when calling the website:
ImproperlyConfigured at /dashboard/student/
The included urlconf core.urls doesn't have any patterns in it
My views.py:
class DashStudentMain(TemplateView):
model_class = None
template_name = 'learn/dashboard/snip_student_1.html'
tab_list = {
("Main", reverse_lazy('dash_student_main_url')),
#("History", reverse_lazy('dash_student_main_url'))
}
active_tab = "Main"
My core.urls:
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
from django.views.generic import RedirectView
from django.conf import settings
admin.autodiscover()
urlpatterns = patterns(
'',
url(r'^$', 'core.views.home', name='home_url'),
url(r'^home', 'core.views.home'),
url(r'^dashboard/', include('tc_learn.dashboard.urls')),
...
)
My tc_learn.dashboard.urls:
from django.conf.urls.defaults import patterns, url
from .views import DashStudentMain, DashStudentHistory
urlpatterns = patterns(
# Student + Tabs
url(r"^", DashStudentMain.as_view()),
url(r"^student/$", DashStudentMain.as_view(), name="dash_student_main_url"),
url(r"^student/history/$", DashStudentHistory.as_view(), name="dash_student_history_url"),
I've
restarted the server, to make sure urls were loaded properly
commented out ("Main", reverse_lazy('dash_student_main_url')) to make sure that the urls.py syntax is fine
deleted the line url(r"^", DashStudentMain.as_view()), since it's not used anyway, but without it /dashboard/student doesn't work at all..
Any idea what I might be missing? Thanks!
EDIT:
It looks like the issue is coming from the tab_list object.
When I directly assign the object via tab_list = reverse_lazy('dash_student_main_url'), the code works fine. When I use it inside a list, it's showing that error. Does anyone know of work-around for this scenario?
Change this code:
tab_list = {
("Main", reverse_lazy('dash_student_main_url')),
#("History", reverse_lazy('dash_student_main_url'))
}
to:
tab_list = [
("Main", reverse_lazy('dash_student_main_url')),
#("History", reverse_lazy('dash_student_main_url'))
]
Contrary to a name you gave the variable, you were not creating a list, but a set. Elements were evaluated immediately at the time of set creation, because sets need to know more about values they contain. Changing it to a proper list will allow the elements to be evaluated lazily, as intended.
In tc_learn.dashboard.urls: you are missing the first argument (empty prefix in your case). Change it to:
urlpatterns = patterns(
'',
url(r"^", DashStudentMain.as_view()),
url(r"^student/$", DashStudentMain.as_view(), name="dash_student_main_url"),
url(r"^student/history/$", DashStudentHistory.as_view(), name="dash_student_history_url"),
)
Also, the first regex should be r"^$" if you want it to represent an empty one
And see if it works. Let me know!