Hi Sam,

On Fri, Nov 12, 2010 at 2:45 PM, Sam Lai <samuel....@gmail.com> wrote:
> 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 hide this with your_patterns() method, or with your_reverse.
It won't be more complex than your URL fix.

>> 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.
Well, such change is meaningful, because of
                bits = normalize(p_pattern)
                lookups.appendlist(pattern.callback, (bits, p_pattern))
                lookups.appendlist(pattern.name, (bits, p_pattern))

appendlist method call convinced me immediately.

>>>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.
I was talking about reverse with more than one result to the same name.
But they do exist already!

> 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.
First I thought you're going to return some instance with reverse
which has get_possibilities.
And you just want RegexURLPattern to register 3 usual regexes for you
instead of one.

Could you please create a patch now -- at least someone will use it.

Maybe you also thought of a patch for this specific case of simple
reversible ORs in the urls?
Examples: (a|b|c) and (?P<a>a|b|c)

>> 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.
>
>



-- 
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.

Reply via email to