On 12 November 2010 19:14, burc...@gmail.com <burc...@gmail.com> wrote: > Ah, sorry, tl;dr happened to me in previous message. > > I used to do the following: > > alternatives = {'html': '/', 'xml': '.xml', 'json': '.json'} > for name, alt in alternatives.iteritems(): > urlpatterns += ('^newitems'+alt+'$', 'views.newitems', {'format': > name}, 'newitems-'+name)
Then you're cluttering urls.py through code. You need to repeat that for every API-enabled URL. > You can make your own method that will do this. > Anyway, only your code can know how to select one of the suggested > alternatives for reverse, so your suggested approach has no > advantages. ... and that's the point. It is the pattern's job to suggest alternatives, not the resolver's. >>This approach requires no changes to existing urls.py > But you have to update all django 3rd party libraries to realize every > url pattern they use can have get_possibilities ! How many third-party libraries out there use custom URL pattern classes, ones that don't subclass from RegexURLPattern? I doubt there are many. But to cater for this fact, the resolver can simply check for the existence of get_possibilities, and if it isn't there, revert to the existing behaviour. For example, if hasattr(pattern, 'get_possibilities'): bits = pattern.get_possibilities() else: bits = normalize(p_pattern) > And you now can't pass secondary pattern into django libs that are not > aware of your feature. Not sure what you're talking about here. I can't see how my changes will break anything, unless a library is using a URLPattern that doesn't extend RegexURLPattern. And again, as above, a small fix can solve that. Just so I'm clear, this is a *backwards-compatible* change. Nothing should break if the above change is incorporated into the original proposal. > So, many-to-many relation between urlpatterns entry and view name only > complicates things. I am not suggesting a many-to-many relationship between urlpatterns and view names. Each urlpattern can still only match 1 view name. It is a many-to-one relationship. Not that this case already exists if you use ? in a regexp in a URL pattern. > On Fri, Nov 12, 2010 at 1:56 PM, burc...@gmail.com <burc...@gmail.com> wrote: >> Hi Sam, >> >> what's the problem with regexp = '^newitems'+SUFFIX+'$' where >> SUFFIX='(/|\.xml|\.json)' ? >> >> And if you need more shortcuts, there are surlex ( >> http://codysoyland.com/2009/sep/6/introduction-surlex/ ) and >> alternatives. >> >> On Fri, Nov 12, 2010 at 11:25 AM, Sam Lai <samuel....@gmail.com> wrote: >>> [First timer participating in the Django dev process, so apologies if >>> I have missed some protocol etc.] >>> >>> First up, this is not about adding an alternate URL >>> resolution/reversal method to the core; I've noticed a fair bit of >>> resistance to that. >>> >>> PROBLEM: >>> I want to make my website available via an API with URLs like this - >>> http://example.com/newitems/ => returns HTML >>> http://example.com/newitems.xml => returns XML >>> http://example.com/newitems.json => returns JSON. >>> >>> To represent this in urls.py, I have to either: >>> a) write a separate url entry for each one >>> b) write 2 url entries, one for newitems/ and another for >>> newitems\.(?P<format>\w+). This is the better option, but still >>> annoying. Plus it forces my view to validate whether or not the format >>> value is acceptable (e.g. is either xml or json). >>> >>> I have to do this for every URL I wish to make available via an API, >>> bloating out my urls.py file. (I'm aware I can use the HTTP-ACCEPT >>> header instead, but there is a need to be able to force the response >>> format in the URL for certain uses.) >>> >>> MY DESIRED SOLUTION: >>> Subclass RegexURLPattern, and override the resolve method so that it >>> will replace a placeholder, e.g. (?#format), with the appropriate >>> regexps (/|\.xml|\.json). Effectively it will perform something >>> similar to this regexp instead - >>> ^newitems(/|(?P<format>(\.xml|\.json))) where the list of accepted >>> formats will be defined in settings. This subclass will be returned >>> using an alternate url(...) call, e.g. murl(...). >>> >>> So my urls.py will look like - >>> urlpatterns = patterns('project.app.views', >>> murl(r'^/(?P<model_id>\d+)(?#format)$', AppView.as_view(), >>> name='app_view1'), >>> ) >>> >>> (For completeness, the view is a CBV, and uses the format arg to >>> determine which template to render, and using what MIME type to >>> respond.) >>> >>> This is a proven way of extending the URL system, as demonstrated by >>> the various projects out there for alternative URL specification >>> syntaxes, e.g. django-easyurls. >>> >>> ROADBLOCK: >>> The issue with this solution is that while resolving will work fine, >>> reversing will not. The list of possible URLs for a particular view is >>> determined by _populate in RegexURLResolver, and is based on the >>> regexp pattern alone. Django doesn't support | in regexps >>> (understandably), and there is no way to supplant this with additional >>> regexps or possibilities at the moment, even though the infrastructure >>> is there during reversal. >>> >>> RESOLUTION - PHASE 1: >>> Because of the friction and work required to fully revamp the URL >>> resolution system, this phase is a short, simple fix that will suffice >>> for most cases where people want to extend the URL resolution system. >>> >>> Refactor out line 218 (in trunk) in django/core/urlresolvers.py: >>> >>> bits = normalize(p_pattern) >>> >>> ... into a separate method in RegexURLPattern: >>> >>> def get_possibilities(self): >>> return normalize(self.regex.pattern) >>> >>> ... and replace line 218 in django/core/urlresolvers.py with: >>> >>> bits = pattern.get_possibilities() >>> >>> That's it. I'll create a patch for this later if the consensus is >>> positive. The above change allows subclassed RegexURLPattern classes >>> to alter what is returned as possible URLs from that pattern. I'm >>> hoping this simple change can be made in Django 1.3. >>> >>> Of course, the possibilities returned still have to be regexps, which >>> leads to phase 2... >>> >>> RESOLUTION - PHASE 2: >>> The ultimate goal should be a URL resolution system that allows >>> alternate URL spec syntaxes to be first-class citizens, allowing >>> regexp based URL specs and say, URI Template specs to exist >>> side-by-side. >>> >>> My plan would be to create an abstract base class for all URLPatterns, >>> which RegexURLPattern will extend. The existing behaviour will mostly >>> stay, except the get_possibilities from phase 1 will be deprecated in >>> favour of a new reverse method. The reverse method will be called by >>> the new universal URLResolver class for matches when reversing URLs, >>> and if a match exists, that will be returned. During _populate(), the >>> new universal URLResolver class will group URLPattern objects by view >>> callback and name, instead of the output of >>> get_possibilities/normalize. >>> >>> This approach requires no changes to existing urls.py; in fact, from a >>> dev perspective, they would only notice the difference if they choose >>> to use alternate URL spec syntaxes. The existing regexp system will >>> work as it has always worked. And it makes sense that the URLPattern >>> object is responsible for resolving and reversing itself, and not the >>> resolver. >>> >>> Until this phase is reached, the API should be considered private so >>> devs are on notice that things will change and may break existing >>> custom URL resolution code. >>> >>> Again, I'm happy to have a crack at making this work if the consensus >>> is positive. >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Django developers" group. >>> To post to this group, send email to django-develop...@googlegroups.com. >>> To unsubscribe from this group, send email to >>> django-developers+unsubscr...@googlegroups.com. >>> For more options, visit this group at >>> http://groups.google.com/group/django-developers?hl=en. >>> >>> >> >> >> >> -- >> Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov, >> MSN: bu...@live.com >> > > > > -- > Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov, > MSN: bu...@live.com > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To post to this group, send email to django-develop...@googlegroups.com. > To unsubscribe from this group, send email to > django-developers+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.