Regular Expression on Django doesn't work - python

I'm relatively new to Django so I am doing this tutorial, but I encountered a problem with regular expressions:
For this view
def viewArticle(request, month, year):
text = "Displaying articles of : %s/%s"%(year, month)
return HttpResponse(text)
I am supposed to create a url like that
url(r'^articles/(\d{2})/(\d{4})', 'viewArticles', name='articles')
and it works perfectly, for example when I enter http://.../articles/12/2014 I get "Displaying articles of: 12 / 2014", as I should.
However, later (on page 27 of the PDF) I am advised to change the url to this:
url(r'^articles/(?P\d{2})/(?P\d{4})', 'viewArticles', name='articles'),
and now it doesn't work anymore. Why could that be and how can I change my code? Thanks for any suggestions!

The tutorial says that you may use named capturing groups here:
(?P<name>...)
Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. Group names must be valid Python identifiers, and each group name must be defined only once within a regular expression. A symbolic group is also a numbered group, just as if the group were not named.
The correct declaration of a named capturing group is (?P<name>...):
url(r'^articles/(?P<month>\d{2})/(?P<year>\d{4})', 'viewArticles', name='articles')

Related

How to find all cells matching a regex with gspread?

So I am very new to programming and I am using python gspread module to use a google sheet as a database.
There's a function for said module called sheet.findall(query, row, column), and this is great, but there's one issue, the query parameter will only look for an exact match, meaning that if i write "DDG", it will not get me the info from a cell with the value of "DDG-87".
After reading the documentation, I found out that you can use python regular expressions to structure the query parameter, so I did that, but there's a problem; The second parameter in re.findall is WHERE to look for, but the issue is that the whole variable is the action of searching, example shown below:
search = sheet.findall(re.findall("[DDG]", The where to search goes here))
As you can see, the whole variable (SEARCH) is the search function, and therefore, I can not specify where to search.
I have tried to set the second parameter of the regex as (SEARCH), but obviously, it won't work.
Any idea or a clue on how I can set the second parameter of re.findall() to be self, or what I can do so that the function doesn't search for an exact match, but if it contains the text?
Thank you.
From the gspread docs:
Find all cells matching a regexp:
criteria_re = re.compile(r'(Small|Room-tiering) rug')
cell_list = worksheet.findall(criteria_re)
So the following should work in your case:
criteria_re = re.compile(r'DDG.*')
search = sheet.findall(criteria_re)

LDAP extensible match filter LDAP_MATCHING_RULE_IN_CHAIN

When I run the following I end up with a good list of results:
base = 'OU=Security Groups,OU=Groups,DC=myserver,DC=com'
criteria = 'CN=My Example'
attributes = ['member', 'groupType', 'description', 'memberOf']
result = connection.search_ext_s(base, ldap.SCOPE_SUBTREE, criteria, attributes, sizelimit=0)
However I can't seem to find anything that helps me when using an LDAP_MATCHING_RULE_IN_CHAIN.
base = 'OU=Security Groups,OU=Groups,DC=myserver,DC=com'
criteria = '1.2.840.113556.1.4.1941:=CN=MatchedRuleChainExample'
attributes = ['member', 'groupType', 'description', 'memberOf']
result = connection.search_ext_s(base, ldap.SCOPE_SUBTREE, criteria, attributes, sizelimit=0)
The above always returns blank. Can anyone help me grasp this? I feel completely lost on how to get through the subgroups in Python.
This criteria syntax 1.2.840.113556.1.4.1941:=CN=MatchedRuleChainExample is wrong.
The string representation of an LDAP extensible match filter must be comprised of the following components in order :
An opening parenthesis
The name of the attribute type, or an empty string if none was provided
The string ":dn" if the dnAttributes flag is set, or an empty string if not
If a matching rule ID is available, then a string comprised of a colon followed by that OID, or an empty string if there is no matching
rule ID
The string ":="
The string representation of the assertion value
A closing parenthesis
To sum it up, it should look like :
([<attr>][:dn][:<OID>]:=<assertion>)
# In your case, fixing the attribute position :
(cn:1.2.840.113556.1.4.1941:=MatchedRuleChainExample)
But there is another issue here : LDAP_MATCHING_RULE_IN_CHAIN only works when used with Distinguished Names (DN) type attributes (like member or memberOf that are commonly used with extensible match filter), but cn is not, so it can't work.
To grab all Security Groups member of CN=My Example, including nested groups, use the memberOf attribute with extensible match and apply it to the group's dn.
# Fixing the attribute type and assertion value :
(memberOf:1.2.840.113556.1.4.1941:=<groupDN>)
Also, you need to filter objectClass to match only group entries (group members could also be users or machines). So in the end, the filter criteria should look like :
(&(objectClass=groupOfNames)(memberOf:1.2.840.113556.1.4.1941:=CN=My Example,OU=Security Groups,OU=Groups,DC=myserver,DC=com))
cf. Active Directory Group Related Searches
Note that LDAP_MATCHING_RULE_IN_CHAIN is available only on Domain Controllers with Windows Server 2003 R2 (or above).

Regular expression url Django

I would like to have one or two urls in following format in django.
e.g. /view/q/node/c/programming....
Here q, c, etc are specific get params and latter on I'll be accessing them either through js or in view.
I have tried following pattern, but it didn't work out.
r'view/(P<q>\w+)/(P<c>\w+)/(P<l>\w+)/(P<o>\w+)/$'
I know that all the get params can be accessed in view if we have ? in url. But I don't want to have ? in url.
Can anyone suggest how to achieve this? Please note that the url can be without any params also. e.g. view/.
Thanks.
You're missing the ? from your Named groups. From the Django docs:
In Python regular expressions, the syntax for named regular-expression groups is
(?P<name>pattern), where name is the name of the group and pattern is some pattern to match.
Thus, referring to your example, it should be:
r'^view/(?P<q>\w+)/(?P<c>\w+)/(?P<l>\w+)/(?P<o>\w+)/$'

Parametrizing a Date on urls.py in Django

I have the following URL definition:
url(r'^date-add/(?P<entity_id>\d+)$', views.date_add, name='date_add'),
That allows me to call date_add function with the following URL:
/app_name/date-add/<id>
I would like to fix this to allow a date. For example:
/app_name/date-add/1/2013-04-23
How should I edit my urls.py definition in order to achieve this?
You can define your URL regex like this:
url(r'^date-add/(?P<entity_id>\d+)/(?P<date>\d{4}-\d{2}-\d{2})/$', views.date_add, name='date_add'),
and the view, obviously would be
def date_add(request, entity_id, date):
#convert to datetime object from string here.
Typically you break it down into named parameters corresponding to the year, month and date:
url(r'^date-add/(?P<entity_id>\d+)/(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})/$', views.date_add, name='date_add_with_param'),
Then you can use datetime.date to construct the datetime in your view, which should receive year, month and day as parameters.
This is the usual pattern in particular for archive views, where the URLs might get more specific as you drill down - /archive/2013/ and /archive/2013/11/ might both be valid, although of course you probably wouldn't have a single regexp matching either. It might be unnecessarily complex compared to the single named pattern regexp karthikr's answer shows, which you could then parse with datetime.strptime.
In either case you can also use somewhat more restrictive regexps if you like, like ones that don't allow a first digit other than 0, 1, 2 or 3 for the month.

Django: Arbitrary number of unnamed urls.py parameters

I have a Django model with a large number of fields and 20000+ table rows. To facilitate human readable URLs and the ability to break down the large list into arbitrary sublists, I would like to have a URL that looks like this:
/browse/<name1>/<value1>/<name2>/<value2>/ .... etc ....
where 'name' maps to a model attribute and 'value' is the search criteria for that attribute. Each "name" will be treated like a category to return subsets of the model instances where the categories match.
Now, this could be handled with GET parameters, but I prefer more readable URLs for both the user's sake and the search engines. These URLs subsets will be embedded on each page that displays this model, so it seems worth the effort to make pretty URLs.
Ideally each name/value pair will be passed to the view function as a parameter named name1, name2, etc. However, I don't believe it's possible to defined named patterns via a regex's matched text. Am I wrong there?
So, it seems I need to do something like this:
urlpatterns = patterns('',
url(r'^browse/(?:([\w]+)/([\w]+)/)+$', 'app.views.view', name="model_browse"),
)
It seems this should match any sets of two name/value pairs. While it matches it successfully, it only passes the last name/value pair as parameters to the view function. My guess is that each match is overwriting the previous match. Under the guess that the containing (?:...)+ is causing it, I tried a simple repeating pattern instead:
urlpatterns = patterns('',
url(r'^browse/([\w]+/)+$', 'app.views.view', name="model_browse"),
)
... and got the same problem, but this time *args only includes the last matched pattern.
Is this a limitation of Django's url dispatcher, and/or Python's regex support? It seems either of these methods should work. Is there a way to achieve this without hardcoding each possible model attribute in the URL as an optional (.*) pattern?
A possibility that you might consider is matching the entire string of possible values within the url pattern portion and pull out the specific pieces within your view. As an example:
urlpatterns = patterns('',
url(r'^browse/(?P<match>.+)/$', 'app.views.view', name='model_browse'),
)
def view(request, match):
pieces = match.split('/')
# even indexed pieces are the names, odd are values
...
No promises about the regexp I used, but I think you understand what I mean.
(Edited to try and fix the regexp.)
I agree with Adam, but I think the pattern in urls.py should be:
... r'^browse/(?P<match>.+)/$' ...
The '\w' will only match 'word' characters, but the '.' will match anything.
I've an alternative solution, which isn't quite different from the previous but it's more refined:
url(r'^my_app/(((list\/)((\w{1,})\/(\w{1,})\/(\w{1,3})\/){1,10})+)$'
I've used unnamed url parameters and a repetitive regexp. Not to get the "is not a valid regular expression: multiple repeat" i place a word at the beginning of the list.
I'm still working at the view receiving the list. But i think ill' go through the args or kwargs.. Cannot still say it exactly.
My 2 cents
Same answer came to me while reading the question.
I believe model_browse view is the best way to sort the query parameters and use it as a generic router.
I think the answer of Adam is more generic than my solution, but if you like to use a fixed number of arguments in the url, you could also do something like this:
The following example shows how to get all sales of a day for a location by entering the name of the store and the year, month and day.
urls.py:
urlpatterns = patterns('',
url(r'^baseurl/location/(?P<store>.+)/sales/(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])/$', views.DailySalesAtLocationListAPIView.as_view(), name='daily-sales-at-location'),
)
Alternativly, you could also use the id of the store by changing (?P<store>.+) to (?P<store>[0-9]+). Note that location and sales are no keywords, they just improve readability of the url.
views.py
class DailySalesAtLocationListAPIView(generics.ListAPIView):
def get(self, request, store, year, month, day):
# here you can start using the values from the url
print store
print year
print month
print date
# now start filtering your model
Hope it helps anybody!
Best regards,
Michael

Categories

Resources