i have in my urls.py
url(r'^(?P<slug>.+)/$', page, name='page'),
url(r'^(?P<slug1>.+)/(?P<slug2>.+)/$', subpage, name='subpage'),
page and subpage are two functions in two different models.
and in my app1/views.py
def page(request, slug):
try :
#some code
except myModel.DoesNotExist:
return HttpResponseNotFound('<h1>not found</h1>')
and imy app2/views.py
def page(request, slug1, slug2):
try :
#some code
except myModel.DoesNotExist:
return HttpResponseNotFound('<h1>not found</h1>')
the problem is i dont get the subpage!
if i change the urls to
url(r'^AAAA(?P<slug>.+)/$', page, name='page'),
url(r'^BBBB(?P<slug1>.+)/(?P<slug2>.+)/$', subpage, name='subpage'),
everything goes well !
how can i solve that ?
Don't use . + in your regular expressions. It will match all characters, including slashes. Usually, you would use [-\w]+, which matches letters a-z and A-Z, digits 0-9, hyphens and underscores.
url(r'^(?P<slug>[-\w]+)/$', page, name='page'),
url(r'^(?P<slug1>[-\w]) /(?P<slug2>[-\w]+)/$', subpage, name='subpage'),
Related
I am working on a project that generates dynamic urls
for eg if you type mysite.com/<yourtexthere> The site should generate a url with mysite.com/yourtexthere (where yourtext here is a slug of a model)and I am able to do that but the problem arises when I put something like this mysite.com/yourtexthere/moretext, Django doesn't match it with any of my existing URL patterns and gives me 404.
I wanted to ask is there a way by which I can treat '/' as just another character and generate unique url mymysite.com/yourtexthere/moretext where yourtexthere/moretext is now the slug.
views.py
def textview(request, slug):
obj, created= Text.objects.get_or_create(slug=slug, defaults={'text':'', 'password':'123'})
return render(request, 'text/textpage.html', {'obj' : obj, 'created' : created})
urls.py
# Only patterns
urlpatterns = [
path('', home, name='home'),
path('<slug:slug>/', textview, name='textview'),
]
From Django models docs:
A slug is a short label for something, containing only letters, numbers, underscores or hyphens.
So the 404 is actually correct, maybe use another field.
Django path converters match strings in the input URL using regex.
The default path converters are pretty basic - source code.
The slugConverter matches any string that only contains characters, numbers, and dashes, not forward slashes. In string yourtexthere/moretext the largest substring it will match is yourtexthere.
The pathConverter matches a string containing any type of character, so the result can contain a forward slash. It will match all of yourtexthere/moretext. So change your urlpatterns to this:
# Only patterns
urlpatterns = [
path('', home, name='home'),
path('<path:slug>/', textview, name='textview'),
]
The pathConverter will match all special characters. If you don't want this you can create your own custom converter with a regex tailored to your needs. For example, you could simply extend the slugConverter to also match strings with forward slashes.
class SlugPathConverter(StringConverter):
regex = '[-a-zA-Z0-9_/]+'
I am trying to pass an ID of a table to my function but I am not sure what's going on.
if I hard code the ID number does work, if I use the (?Pd+) with d+ so it use as many digits, like in the tutorials. doesn't work. should this be different?
thanks guys.
my urls
from django.conf.urls import patterns, include, url
from polls import views
urlpatterns = patterns('',
#url(r'^main_site/$', views.main_site),
url(r'^vote/$', views.vote),
url(r'^stadistics/$', views.stadistics),
# using it like this doesn't work
url(r'^vote/Restaurant_Info/(?P<rest_id>d+)/$', views.restaurant_menu),
#testing the info of the restaurant
# hard coding the id of the restaurant does work
url(r'^vote/Restaurant_Info/4/$', views.restaurant_menu),
my view
def restaurant_menu(request, rest_id="0"):
response = HttpResponse()
try:
p = Restaurant.objects.get(id=rest_id)
response.write("<html><body>")
response.write("<p>name of the restaurant</p>")
response.write(p.name)
response.write("</body></html>")
except Restaurant.DoesNotExist:
response.write("restaurant not found")
return response
You're missing a backslash in your expression, currently d+ matches the character d literally "one or more" times. The backslash in combination with a literal character creates a regular expression token with special meaning.
Therefore, \d+ will match digits 0 to 9 "one or more" times.
url(r'^vote/Restaurant_Info/(?P<rest_id>\d+)/$', views.restaurant_menu)
You're missing a slash. It should be (?P<rest_id>\d+)
url(r"^vote/Restaurant_Info/(?P<rest_id>\d+)/$", views.restaurant_menu),
HTML form:
<form id="save_form" method="post" action="{% url 'project_save' usernames=username project_name='lion' %}">
Notice the arg 'project_name's value is 'lion'
views.py:
def projectz_save(request, usernames, project_name):
template = loader.get_template('project_view/index.html')
context = RequestContext(request, {"username": usernames, "project": project_name})
return HttpResponse(template.render(context))
urls.py:
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^(?P<usernames>\w+)(?P<project_name>\w+)save$', views.projectz_save, name='project_save'),
)
What happens is that only the 'n' in 'lion' is being passed as an argument. When I re-render the page, the template variable "project" now has the value 'n' instead of 'lion.' Any idea why this is happening?
It happens if I use a variable instead of a string (which is obviously the ultimate goal), but even simplified down to a simple string it's still happening.
Your problem is that while the template is correctly constructing the URL, your urls.py regexp is too greedy.
Specifically, you have no divider between your usernames named group and your project name named group:
r'^(?P<usernames>\w+)(?P<project_name>\w+)save$'
Given any sequence of word characters, all but the last will be matched by the \w+ in the usernames group. The last will be matched by the project_name group, because + requires at least one character. So if username in the template is 'johndoe', the url tag will construct the URL:
johndoelionsave
The regexp will then match johndoelio as the usernames group, since all of those are matched by \w+, n as the project_name group, since it's matched by \w+, and then the fixed save and end-of-string parts.
Your best fix will be to break up the URL pattern so that the parsing is unambiguous. I suggest:
r'^(?P<usernames>\w+)/(?P<project_name>\w+)/save$'
In which case the template tag will produce:
johndoe/lion/save
and the regexp will parse out the details you want.
I have urls where spaces are replaced with the "-" character.
So I made a url regex like this:
url(r'^(?P<item_url>(\w+-?)*)/$', 'detail'),
my view:
def detail(request, item_url):
i = get_object_or_404(Page, url=item_url,published=True)
return render_to_response('item/detail.html', {'item':i},
context_instance=RequestContext(request))
Unfortunately this keeps django extremely busy on urls with more than 20 characters. The process hangs for 20sec - 1 minute and then returns the correct result. Is this based on a wrong regex I'm using?
Try the following url pattern:
url(r'^(?P<item_url>[\w-]+)/$', 'detail'),
[\w-]+ will match one or more alphanumeric characters or hyphens.
So I have this URL scheme:
(r'^test/(?P<name>\d+)/', 'test'),
def test(request, name):
html = "it worked"
return HttpResponse(html)
however, when I go to the following URL, I get a 404 error:
http://127.0.0.1:8000/test/words/
What am I doing wrong?
You probably meant to use \w instead, e.g.:
(r'^test/(?P<name>\w+)/', 'test'),
\d matches only digits; \w matches any alphanumeric character.
Python Regular Expression HOWTO by A.M. Kuchling.