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.

Reply via email to