How to use Django's include without a string literal? - python

I just started up with django.
Following this tutorial, I ended up with the following urls.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
This links to polls.urls.py which has its own router.
The part I don't like is the string literal 'polls.urls' which is, well... a string literal.
I would like to somehow reference the file directly using some of python's power, and have AT LEAST my IDE protect me.
What happens if I want to move that polls.urls.py file, or rename it, or rename polls? Should I trust my IDE to catch a reference from a string literal?
This is almost like doing this monstrosity, and is very hard for me to accept as the best practice.
It just seems odd to me.
Is there a way to use something less prone to errors than string literals in django's routers?

I don't see problems with using string literals as URLconf is loaded prior to starting of server (runserver)
If there is a problem you would get ModuleNotFound error
From source of include() :
if isinstance(urlconf_module, six.string_types):
urlconf_module = import_module(urlconf_module)
You would see good amount of import_module usage through Django framework and string literals.
Your IDE would know if there is unresolved reference (Pycharm does)

So from what I understand or what I know there are two ways of url mapping using the
path' orurl`
for path method you bound to do what you did that is:
from django.urls import path, include
but you are to also import your views.py
For second method your are to:
from django.conf.urls import url
then your are to import your views there as:
from .views import home_page
home_page being a function or class in your views.py
Example of mapping
url(r'^home/$', home_page),
so no need to actually to actually create urls.py if you use this method

Related

Django cant be reached via parameterized url

Hello StackOverflow community,
I'm currently learning how to use the library Django combined with Python. However, I've ran into some issues which are somehow strange. My situation is the following. I have a project called "animals" which is the base of the Django application. My app is called "polls". Then I've defined the following views.
polls/views.py
from django.shortcuts import render
from django.http import HttpResponse
def animals(request, animal_id):
return HttpResponse("%s" % animal_id)
def index(request):
return HttpResponse('Hello world')
So far, so good. Unfortunatly I can't say the same about the urlpatterns.
polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.index,name='index'),
# Redirects to localhost:8000/polls/<animal_id>
path('<int:animal_id>/',views.animals,name='animals')
]
Whenever I want to navigate to the url "localhost:8000/polls/10/" Django reminds me of the fact, that the url is not accepted by the application and a 404 Error is thrown inside my browser. Am I missing something here?
UPDATE
I've managed to resolve the problem by fixing a rather trivial error. While the polls/urls.py was alright, the problem lay inside the animals/urls.py file. This file looked like this:
animals/urls.py
from django.conf.urls import url
from django.contrib import admin
from django.urls import include,path
urlpatterns = [
url(r'^admin/', admin.site.urls),
path('polls',include('polls.urls')),
]
As one can see, the "polls" path is not finished with a "/" sign. This indicates to Django that my desired route would be localhost:8000/polls where is any integer I add to the url. However, you have to add the slash at the end. Otherwise Django won't work as expected.

Django: The included urlconf core.urls doesn't have any patterns in it

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!

How to define url which accept everykind of strings in django

In django, I defined url like that
(r'^checkstring/(?P<string>\w+)/$',views.check_str,name='check str')
But, When i enter string inputs like ibrahim.yilmaz, ibrahi!m or ibrahim#ibrahim.com, it returns http 404.
So how can i write the url which accept everykind of string?
any help will be appreciated.
İbrahim
Django uses regular expressions to match incoming requests. In python a dot (.) matches any character except a newline. See docs for more information and try:
(r'^checkstring/(?P<string>.+)/$',views.check_str,name='check str')
Also keep in mind that this will accept any character (including the forward slash) which may not be desirable for you. Be sure to test to make sure everything works as you would expect.
In Django >= 2.0, you can implement in the following way.
from django.urls import path
urlpatterns = [
...
path('polls/<string>/$','polls.views.detail')
...
]
For Django 2.0
import re_path in urls.py file
like this:from django.urls import re_path
then in the urlpatterns write the following code:
urlpatterns = [ re_path('prefixs/.*', your_ViewClass_name.as_view()), ]

Django - The included urlconf doesn't have any patterns in it

My website, which was working before, suddenly started breaking with the error
ImproperlyConfigured at / The included urlconf resume.urls doesn't
have any patterns in it
The project base is called resume. In settings.py I have set
ROOT_URLCONF = 'resume.urls'
Here's my resume.urls, which sits in the project root directory.
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Example:
# (r'^resume/', include('resume.foo.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls)),
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
#(r'^employer/', include(students.urls)),
(r'^ajax/', include('urls.ajax')),
(r'^student/', include('students.urls')),
(r'^club/(?P<object_id>\d+)/$', 'resume.students.views.club_detail'),
(r'^company/(?P<object_id>\d+)/$', 'resume.students.views.company_detail'),
(r'^program/(?P<object_id>\d+)/$', 'resume.students.views.program_detail'),
(r'^course/(?P<object_id>\d+)/$', 'resume.students.views.course_detail'),
(r'^career/(?P<object_id>\d+)/$', 'resume.students.views.career_detail'),
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': 'C:/code/django/resume/media'}),
)
I have a folder called urls and a file ajax.py inside. (I also created a blank init.py in the same folder so that urls would be recognized.) This is ajax.py.
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^star/(?P<object_id>\d+)$', 'resume.students.ajax-calls.star'),
)
Anyone know what's wrong? This is driving me crazy.
Thanks,
TL;DR: You probably need to use reverse_lazy() instead of reverse()
If your urls.py imports a class-based view that uses reverse(), you will get this error; using reverse_lazy() will fix it.
For me, the error
The included urlconf project.urls doesn't have any patterns in it
got thrown because:
project.urls imported app.urls
app.urls imported app.views
app.views had a class-based view that used reverse
reverse imports project.urls, resulting in a circular dependency.
Using reverse_lazy instead of reverse solved the problem: this postponed the reversing of the url until it was first needed at runtime.
Moral: Always use reverse_lazy if you need to reverse before the app starts.
Check your patterns for include statements that point to non-existent modules or modules that do not have a urlpatterns member. I see that you have an include('urls.ajax') which may not be correct. Should it be ajax.urls?
check for correct variable name in your app, if it is "
urlpatterns
" or any thing else.
Correcting name helped me
IN my case I got this error during deployment.
Apache kept giving me the "AH01630: client denied by server configuration" error.
This indicated that was wrong with apache configuration. To help troubleshoot I had turned on Debug=True in settings.py when I saw this error.
In the end I had to add a new directive to the static files configuration inside apache config. When the static files were not accessible and Debug in django settings was set to true this error was getting triggered somehow.
I got this error when trying to reverse (and reverse_lazy) using RedirectView and parameters from the url. The offending code looked like this:
from django.views.generic import RedirectView
from django.core.urlresolvers import reverse
url(r'^(?P<location_id>\d+)/$', RedirectView.as_view(url=reverse('dailyreport_location', args=['%(location_id)s', ]))),
The fix is to use this url in urlpatterns:
from django.views.generic import RedirectView
url(r'^(?P<location_id>\d+)/$', RedirectView.as_view(url='/statistics/dailyreport/%(location_id)s/')),
ANSWER: The fix so you can still use the name of the url pattern:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
urlpatterns = patterns('',
....
url(r'^(?P<location_id>\d+)/$', lambda x, location_id: HttpResponseRedirect(reverse('dailyreport_location', args=[location_id])), name='location_stats_redirect'),
....
)
In my case, it was because of tuple unpacking. I only had one url and the root cause for this ImproperlyConfigured error was
TypeError: 'URLPattern' object is not iterable
I used a trailing comma at the end and it resolved the issue.
urlpatterns = (url(...) , )
Check the name of the variable.
The cause of my error was using "urlspatterns" in lieu of "urlpatterns".
Correcting the name of the variable solved the issue for me.
In my case I had the following error:
ImproperlyConfigured: The included URLconf does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.
The url patterns were valid, but the problem was an Import error caused by a typo. I typed restframework instead of rest_framework.
Note: For some reason, for me this error also went away after I saved another file. So the first time the error appeared, I had saved a file in which I specified the wrong widget in the forms.py file:
extra_field = forms.CharField(widget=forms.TextField())
instead of
extra_field = forms.CharField(widget=forms.TextInput())
After changing it to the correct version (TextInput) and saving the forms.py file, the error was still showing in my console. After saving another file (e.g. models.py) the error disappeared.
Check the imported modules in views.py if there is any uninstalled modules you found remove the module from your views.py file.
It's Fix for me
django.urls.reverse()-->django.urls.reverse_lazy()
This will instantly solve it.

Django - Website Home Page

I've been having a look at Django and, from what I've seen, it's pretty darn fantastic. I'm a little confused, however, how I go about implementing a "home page" for my website? Would it be a separate app, or just a view within the project, or what?
There's no real rule for this, But one thing I like to do is actually arrange for the index access to redirect to another spot. If you prefer, though, you can just give the index page a plain view.
That said, It's probably a good idea to keep all your code in an actual app, so that you can refactor it more easily, and so that it appears on the python path as a normal module. Putting views in the project rather than an app seems to cause more headaches than it solves.
I just found my original approach (direct_to_template) is deprecated in Django 1.5
Instead, use a TemplateView to achieve the same result
from django.conf.urls import patterns, include, url
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^$',
TemplateView.as_view(template_name='index.html'),
name='index'),
)
(For Django 1.4) You can setup a direct_to_template url within ./project/project/urls.py
from django.conf.urls import patterns, include, url
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
(r'^$', direct_to_template, { 'template': 'index.html'}),
# add urls to apps here
)
For both, place the template (index.html) in your TEMPLATE_DIRS root. This is one approach to create a homepage without implementing an entire app. There are many ways to make this happen as others have noted.
The easiest way is using Django's "Flatpages". See this link for more info: http://docs.djangoproject.com/en/dev/ref/contrib/flatpages/

Categories