django 1.7 how to pass arguments to function regular expressions - regex

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),

Related

Django URL issue with regular expressions

I am new to Python, Django 1.9 and overall regular expressions. So I am trying to write something like this within urls.py
search/doc_name/language/?id
where doc_name, allow for any name/case/length etc. like so: 'My Fave Doc 12'
where language, allow two letters like so: 'en'
where id, allows only numbers.
This is what I have, can someone point out where I went wrong?
url(r'^search/[\w-]+/[a-z]{2}+/(?P<id>[0-9]+)$', '....
The doc_name doesn't allow spaces. Add a space in the character set if you want one. Make sure you put it before the dash ([\w -]+). If other whitespaces are allowed, used \s instead ([\w\s-]+).
Also the language would currently match any even amount of letters. Remove the + and leave only [a-z]{2}. + means repeat one or more times, anything is matched only once by default.
You should really avoid to have spaces in you URL, I suggest the following:
url format: /search/<doc_name>/<id>/?lang=<language>
in urls.py:
url(r'^search/(?P<doc_name>[\w]+)/(?P<id>[0-9]+)/$'), your_view)
in views.py:
lang = request.GET.get('lang', 'en')
doc_name = request.POST.get('doc_name')
id = request.POST.get('id')

Regular expression in URL for Django slug

I have 2 URL's with a slug field in the URL.
url(r'^genres/(?P<slug>.+)/$', views.genre_view, name='genre_view'),
url(r'^genres/(?P<slug>.+)/monthly/$', views.genre_month, name='genre_month'),
The first one opens fine but the second one gives a DoesNotExist error saying Genres matching query does not exist.
Here is how I'm accessing the 2nd URL in my HTML
<li>Monthly Top Songs</li>
I tried to print the slug in the view. It is passed as genre_name/monthly instead instead of genre_name.
I think the problem is with the regex in the URLs. Any idea what's wrong here?
Django always uses the first pattern that matches. For urls similar to genres/genre_name/monthly your first pattern matches, so the second one is never used. The truth is the regex is not specific enough, allowing all characters - which doesn't seem to make sense.
You could reverse the order of those patterns, but what you should do is to make them more specific (compare: urls.py example in generic class-based views docs):
url(r'^genres/(?P<slug>[-\w]+)/$', views.genre_view, name='genre_view'),
url(r'^genres/(?P<slug>[-\w]+)/monthly/$', views.genre_month, name='genre_month'),
Edit 2020:
Those days (since Django 2.0), you can (and should) use path instead of url. It provides built-in path converters, including slug:
path('genres/<slug:slug>/', views.genre_view, name='genre_view'),
path('genres/<slug:slug>/monthly/', views.genre_month, name='genre_month'),
I believe that you can also drop the _ from the pattern that #Ludwik has suggested and revise to this version (which is one character simpler :) ):
url(r'^genres/(?P<slug>[-\w]+)/$', views.genre_view, name='genre_view'),
url(r'^genres/(?P<slug>[-\w]+)/monthly/$', views.genre_month, name='genre_month'),
Note that \w stands for "word character". It always matches the ASCII characters [A-Za-z0-9_]. Notice the inclusion of the underscore and digits. more info
In Django >= 2.0, slug is included in URL by doing it like below.
from django.urls import path
urlpatterns = [
...
path('articles/<slug:some_title>/', myapp.views.blog_detail, name='blog_detail'),
...
]
Source: https://docs.djangoproject.com/en/2.0/ref/urls/#django.urls.path

Wrong url regex keeps django busy

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.

Django dynamic url. what am i doing wrong?

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.

Django urlpatterns frustrating problem with trailing slashes

All of the examples I can find of urlpatterns for django sites have a separate entry for incoming urls that have no leading slash, or the root folder. Then they handle subfolders on each individual line. I don't understand why a simple
/?
regular expression doesn't permit these to be on one simple line.
Consider the following, let's call the Django project Baloney and the App name is Cheese. So in the project urls.py we have something like this to allow the apps urls.py to handle it's requests...
urlpatterns = patterns('',
(r'^cheese/', include('Baloney.Cheese.urls')),
)
then inside of the Cheese apps urls.py, I don't understand why this one simple line would not trigger as true for all incoming url subpaths, including a blank value...
urlpatterns = patterns('',
(r'^(?P<reqPath>.*)/?$', views.cheeseapp_views),
)
Instead, it matches the blank case, but not the case of a value present. So...
http://baloneysite.com/cheese/ --> MATCHES THE PATTERN
http://baloneysite.com/cheese/swiss --> DOES NOT MATCH
Basically I want to capture the reqPath variable to include whatever is there (even blank or '') but not including any trailing slash if there is one.
The urls are dynamic slugs pulled from the DB so I do all the matching up to content in my views and just need the url patterns to forward the values along. I know that the following works, but don't understand why this can't all be placed on one line with the /? regular expression before the ending $ sign.
(r'^$', views.cheeseapp_views, {'reqPath':''}),
(r'^(?P<reqPath>.*)/$', views.cheeseapp_views),
Appreciate any insights.
I just tried a similar sample and it worked as you wrote it. No need for /?, .* would match that anyway. What is the exact error you are getting? Maybe you have your view without the request parameter? I.e. views.cheeseapp_views should be something like:
def cheeseapp_views(request, reqPath):
...
Edit:
The pattern that you suggested catches the trailing slash into reqPath because * operator is greedy (take a look at docs.python.org/library/re.html). Try this instead:
(r'^(?P<reqPath>.*?)/?$', views.cheeseapp_views)
note it's .*? instead of .* to make it non-greedy.