For some reason Django is not appending a slash at the end of variables that contain numeric characters:
test_A -- works (goes to test_A/)
test_1 -- does not (doesn't append the / at the end - giving me a 404)
I do have middleware installed and APPEND_SLASH = True.
Any thoughts? Thanks!
url.conf:
from django.conf.urls import patterns, url
from dashboard import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^environment/(?P<environment_name_url>\w+)/$', views.environment, name='environment'),)
models.py:
from django.db import models
class Environment(models.Model):
name = models.CharField(max_length=128, unique=True)
def __str__(self):
return self.name
views.py:
def environment(request, environment_name_url):
environment_name = environment_name_url.replace('_', ' ')
context_dict = {'environment_name': environment_name}
try:
environment = Environment.objects.get(name=environment_name)
pages = Page.objects.filter(environment=environment)
context_dict['pages'] = pages
context_dict['environment'] = environment
except Environment.DoesNotExist:
pass
return render(request, 'dashboard/environment.html', context_dict)
Error:
Using the URLconf defined in dashboard_project.urls, Django tried these URL patterns, in this order:
1. ^admin/
2. ^dashboard/ ^$ [name='index']
3. ^dashboard/ ^environment/(?P<environment_name_url>\w+)/$ [name='environment']
4. media/(?P<path>.*)
The current URL, dashboard/environment/test_1, didn't match any of these.
You have to extend your regular expressions. The problem is not that the slash is not appended, the problem is that none of the urls matches (with or without the slash).
Simple solution, to include the dot you should update your regular expression to also allow a dot:
url(r'^environment/(?P<environment_name_url>[\w\.]-)/$', views.environment, name='environment'),)
Your could improve it further to also allow a dash:
url(r'^environment/(?P<environment_name_url>[\w\.-]+)/$', views.environment, name='environment'),)
The latter would even allow /test-1.1_10/
Related
I have a small resume site that is not rendering a different template upon hitting a reversed URL.
site/scripts/templates/scripts/index.html:
<p>were at main</p>
python
<br/>
bash
These links 'python' and 'bash' work in the URL bar, they take us to localhost:scripts/bash/ and localhost:scripts/python/, but the exact same webpage is displayed (index.html, or localhost:scripts/)
site/scripts/urls.py:
from django.conf.urls import patterns, include, url
from scripts import views
urlpatterns = patterns('',
url(r'$', views.index, name='index'),
url(r'python/$', views.access_python, name='python'),
url(r'bash/$', views.access_bash, name='bash'),
)
site/scripts/views.py:
from django.shortcuts import render
def index(request):
return render(request, 'scripts/index.html')
def access_python(request):
return render(request, 'scripts/python.html')
def access_bash(request):
return render(request, 'scripts/bash.html')
site/urls.py (main folder w/ settings.py):
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'scripts/', include('scripts.urls', namespace='scripts')),
)
clicking 'bash' should retrieve:
site/scripts/templates/scripts/bash.html:
<p>we're at bash</p>
Why would a reverse lookup reach the correct URL, but not call the associated view that that URL pattern wants? Thank you
The index regex was catching any possible pattern, since it matched any end of string. I found out by moving the index pattern after the other 2. It should be:
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^python/$', views.access_python, name='python'),
url(r'^bash/$', views.access_bash, name='bash'),
)
Any blank index urls (r'^$') need both start and end of string, to match the empty string after the first part of that pattern (in this case, 'scripts/')
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!
i am new to Django and i have some problem with Django URL dispatcher.
I have "prometfire" project and "homepage" app.
My goal is to connect this paths to their view functions:
127.0.0.1:8000 --> "homepage_view"
127.0.0.1:8000/welcome --> "welcome_view"
"homepage_view" works fine, but when i go to 127.0.0.1:8000/welcome i have same result as in "homepage_view", instead of "welcome_view" result.
Am i missing something?
Django 1.5
Python 2.7
#urls.py in prometfire
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', include('homepage.urls')),
url(r'^welcome/', include('homepage.urls')),
url(r'^admin/', include(admin.site.urls)),
)
#urls.py in homepage app
from django.conf.urls import patterns, include, url
urlpatterns = patterns('homepage.views',
url(r'^$', 'homepage_view'),
url(r'^welcome/', 'welcome_view'),
)
#views.py in homepage app
from django.shortcuts import render_to_response
from django.http import HttpResponse
def homepage_view(request):
return render_to_response('homepage.html',
{'name': 'bob'}
)
def welcome_view(request):
return HttpResponse('Welcome')
Your problem is that you are including your homepage urls twice. Remove the second entry
url(r'^welcome/', include('homepage.urls')),
This is explained in the docs on including other url confs
Whenever Django encounters include() (django.conf.urls.include()), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
In your case, the 'welcome/' is removed from the url, which leaves '', which is matched by the url pattern for the homepage.
That's because it never enters the second condition for the app, it verifies the condition at the url root conf, welcome/, and after that goes directly to ^$ in the app. A solution would be remove the welcome/ from the url root.
The first welcome definition is redundant and is causing the "bug".
How do I nest url calls in django? For example, if I have two models defined as
class Post(models.Model):
title = models.CharField(max_length=50)
body = models.TextField()
created = models.DateTimeField(auto_now_add=True, editable=False)
def __unicode__(self):
return self.title
#property
def comments(self):
return self.comment_set.all()
class Comment(models.Model):
comment = models.TextField()
post = models.ForeignKey(Post)
created = models.DateTimeField(auto_now_add=True)
With the following url files
root url
urlpatterns = patterns('',
url(r'^post/', include('post.urls')),
)
post url
urlpatterns = patterns('',
url(r'^$', views.PostList.as_view()),
url(r'^(?P<pk>[0-9]+)/$', views.PostDetail.as_view()),
url(r'^(?P<pk>[0-9]+)/comments/$', include('comment.urls')),
)
comment url
urlpatterns = patterns('',
url(r'^$', CommentList.as_view()),
url(r'^(?P<pk>[0-9]+)/$', CommentDetail.as_view()),
)
But when I go to /post/2/comments/1, I am given a Page not found error stating
Using the URLconf defined in advanced_rest.urls, Django tried these URL patterns, in this order:
^post/ ^$
^post/ ^(?P<pk>[0-9]+)/$
^post/ ^(?P<pk>[0-9]+)/comments/$
The current URL, post/2/comments/1, didn't match any of these.
This is not a problem though when I visit /post/2/comments Is this not allowed by django to have nested URL calls like this?
I think is probably because you're finishing the regex with the dollar sign $. Try this line without the dollar sign:
...
url(r'^(?P<pk>[0-9]+)/comments/', include('comment.urls')),
...
Hope it helps!
You have a $ at the end of r'^(?P<pk>[0-9]+)/comments/$'.
That means Django will only match with that URL when there is nothing after that.
So any longer URLs currently won't be considered. Therefore, you need to update the regular expression to:
url(r'^(?P<pk>[0-9]+)/comments/', include('comment.urls')),
Above Django 2.0 you can use simply...
urlpatterns = [
path('<pk>/comments/', include('comment.urls')),
]
I'm having trouble extracting a string from my URL. Here's what I've got.. it keeps 404ing.
urls.py:
urlpatterns = patterns('',
(r'^user/(?P<username>\w{0,50})/$', profile,),
)
views.py:
def profile(request, username):
...
return ...
See anything obvious? Need more? Any help is appreciated.
I usually a /?$ at end of url pattern.
It is a common mistake and some browser add or not a trailing '/'.
Have you imported your views module at the top of your URL file?
from views import profile
urlpatterns = patterns('',
(r'^user/(?P<username>\w{0,50})/$', profile),
# also removed trailing comma after profile
)
# alternative
urlpatterns = patterns('',
(r'^user/(?P<username>\w{0,50})/$', 'views.profile'),
)
Have you got DEBUG = True in your settings file? That'll help find errors with a stacktrace that you should show us.