Re: Modify get_or_create() to use field lookups parameters for values

2014-06-09 Thread gavinwahl
I don't think this is possible to do generally. What would count__gt=1 or 
pub_date__month=12 do?

On Friday, June 6, 2014 3:50:08 PM UTC-6, Patrick Bregman wrote:
>
> Hi all,
>
> First of, I'm new to this list so please tell me if there's something that 
> can be done better. It's the best way to learn for me ;)
>
> Recently I've been doing some reworking of an old (think Django 1.1 or 
> 1.2) webapp of mine into the latest and greatest of Django. In the process 
> I modified some models, and thought that *get_or_create* would be perfect 
> to replace boring try / except cases. Except that it didn't really work as 
> planned. I tried to do a *get_or_create(name__iexact=value, 
> defaults={'slug': slugify(value)})*. I expected this to be smart enough 
> to know that it should fill the field *name* based on the *name__iexact* 
> parameter. Apparently it isn't :) In this case you'd need to add a 
> definition for *name* to the *defaults* dict to get the value into the 
> newly created model. I'm not sure, but I personally think this shouldn't be 
> that hard to fix. It's basically checking (and removing) known field 
> lookups or simply everything after a double underscore, and using that as a 
> field name. Or at least, that's my view on it.
>
> The big question is:
> 1. Is this behavior that exotic that I'm the first one to notice, or did I 
> do a wrong search on Google?
> 2. Would this indeed be as easy (or comparably easy) as I think? 
> 3. Is this behavior we actually want in Django?
>
> If the answer to 2 and 3 are yes, I'll look into giving it a try to making 
> a patch for this myself.
>
> Regards,
> Patrick Bregman
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/11c6e6a3-0b73-41a5-a743-83f7ad828817%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Josh Smeaton
> However, I think having some special case code in filter(), annotate() 
and anything else that takes expressions would be OK

I strongly disagree with this. Expressions are context insensitive at the 
moment, which means they can be used anywhere. If we start externalising 
behaviour based on the context of use, it'll lead us to some very confusing 
code and a tonne of special cases. It would be slightly better if you could 
check the context from the `prepare()` method (are we preparing order_by or 
not), but then I think we'll run into issues where the prepare breaks for 
3rd party backends - by checking private data. I really do think we'd be 
better off documenting that __neg__ is reserved by Expressions for 
Ordering, and leave it at that.

I'm surprised how easily expressions slotted in to the order_by - I thought 
it'd take a lot more work. Good stuff I think. Some questions:

- should expressions in order_by support random ordering (?) ? I don't 
think so, but I haven't ever had a need for random ordering so I'm not sure.
- could we reduce the complexity of the order_by machinery by forcing all 
arguments (internally) to be expressions? `order_by('field_a') -> 
order_by(F('field_a'))` etc

These are open questions, not necessarily directed at Tim.

> I haven't yet implemented the LowerCase and related functions

I think we can build out a handy little library of utility functions like 
Lower and Coalesce that could(should) be included directly in django. But 
it'll also open up, to library developers, the ability to easily develop 
backend specific structures, similar to parts of the 
django.contrib.postgres kickstarter.

Cheers

On Tuesday, 10 June 2014 06:31:28 UTC+10, Tim Martin wrote:
>
> On Monday, 9 June 2014 21:28:51 UTC+1, Tim Martin wrote:
>>
>>
>> On Monday, 9 June 2014 20:44:08 UTC+1, Tim Martin wrote:
>>>
>>>
>>> I'll go ahead and try to implement this using __neg__() to invert the 
>>> ordering.
>>>
>>>
>> It's still pretty rough, but there's some code in 
>> https://github.com/timmartin/django/tree/order_by_expressions that 
>> appears to work. In particular, I haven't yet implemented the LowerCase and 
>> related functions (I have one, but it's just a test hack), but that should 
>> just be boiler-plate.
>>
>>
> And I should have noted that I haven't implemented detection of negation 
> in contexts other than ORDER BY. It's not easy to do it cleanly with the 
> simple approach I've got at the moment. The code could just check that 
> get_ordering() returns ASC, but a) that's gross and b) it doesn't solve the 
> problem of having unary negative on a subexpression, which would get 
> ignored.
>
> Tim
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/3f909f23-00a5-4bec-a21c-1333cec912b9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Proposal: variable argument lists for templatetags, in templates.

2014-06-09 Thread Russell Keith-Magee
On Mon, Jun 9, 2014 at 3:38 PM, Przemek Czerkas  wrote:

> Hi,
>
> In this ticket https://code.djangoproject.com/ticket/13956 (Indefinite
> args for simpletags and inclusion tags) a support for *args and **kwargs
> for simple_tag, inclusion_tag and assignment_tag was added.
>
> I think that one piece is still missing. How about allowing to pass
> *args/**kwargs to templatetag arguments:
>
> {% some_tag [positional_args] [named_args] *args **kwargs %}
>
> where args is a list, kwargs is a dict?
>
> With this new syntax, the resolution of variable arguments would had to be
> moved to the render() phase, as well as some of the argument checking (e.g.
> {% with kwargs %} case for empty kwargs).
>
>
Hi Przemek,

I'm not entirely certain I understand what you're proposing here.
simple_tag, inclusion_tag and assignment_tag are all utility classes that
you use to produce template tags; however, all the "native" template tags
have their own implementations - which includes, for the most part, their
own parsing infrastructure.

Note that I'm not necessarily defending this arrangement -- In the past,
this has been the cause of inconsistencies in argument handling between
tags. However, it is the status quo, and it needs to be taken into account
- if only because The side effect of this arrangement is that any custom
template tags out there are relying on the fact that variable resolution
*doesn't* happen in the render phase - at least, not in any automated or
semi-automated way.

So -  at a high level API level, what you are suggesting sounds interesting
- *args and **kwargs are a powerful mechanism in python, and I can see how
they might be useful in the context of template tags as a general feature -
but I'm not sure I see how this would manifest in practice. The only two
approaches I can see are:

1) a backwards incompatible change at the root level of template tag
design, or

2) a manual change to each of Django's internal template tags - which would
represent a lot of code churn to satisfy a use case that isn't entirely
clear.

Are you able to clarify how you would see this change happening in practice?

Yours,
Russ Magee %-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAJxq84_VzjUmkZdKKB_f0SHMkZVaRHShwsWTW93cq0vuj2tEYQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Tim Martin
On Monday, 9 June 2014 21:28:51 UTC+1, Tim Martin wrote:
>
>
> On Monday, 9 June 2014 20:44:08 UTC+1, Tim Martin wrote:
>>
>>
>> I'll go ahead and try to implement this using __neg__() to invert the 
>> ordering.
>>
>>
> It's still pretty rough, but there's some code in 
> https://github.com/timmartin/django/tree/order_by_expressions that 
> appears to work. In particular, I haven't yet implemented the LowerCase and 
> related functions (I have one, but it's just a test hack), but that should 
> just be boiler-plate.
>
>
And I should have noted that I haven't implemented detection of negation in 
contexts other than ORDER BY. It's not easy to do it cleanly with the 
simple approach I've got at the moment. The code could just check that 
get_ordering() returns ASC, but a) that's gross and b) it doesn't solve the 
problem of having unary negative on a subexpression, which would get 
ignored.

Tim

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0018b11b-0e82-44d8-856c-0d43f435013e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Tim Martin

On Monday, 9 June 2014 20:44:08 UTC+1, Tim Martin wrote:
>
>
> I'll go ahead and try to implement this using __neg__() to invert the 
> ordering.
>
>
It's still pretty rough, but there's some code in 
https://github.com/timmartin/django/tree/order_by_expressions that appears 
to work. In particular, I haven't yet implemented the LowerCase and related 
functions (I have one, but it's just a test hack), but that should just be 
boiler-plate.

Tim 

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/358be002-4bcf-4573-b12b-c5542eb8f35c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Daniel Moisset
oh, nevermind, I misread the syntax spec for the order by clause


On Mon, Jun 9, 2014 at 5:07 PM, Michael Manfre  wrote:

> Each expression must be able to define it's own ordering because order_by
> allows you to define a sort based upon multiple expressions.
>
>
> On Mon, Jun 9, 2014 at 4:00 PM, Daniel Moisset 
> wrote:
>
>> I see everyone trying to put the direction (ascending vs decending)
>> inside the expression, while it's actually a property of the ordering
>> clause. Wouldn't it make more sense and avoid ambiguities to do:
>>
>> qs.order_by(..., descending=True)
>>
>> ?
>>
>> Then you can add functions (and even a __neg__ operator to fields mapped
>> to SQL unary minus) and still have a clear separation of functions vs order
>> direction.
>>
>> D.
>>
>>
>>
>> On Mon, Jun 9, 2014 at 4:44 PM, Tim Martin  wrote:
>>
>>> My concern about the filter(foobar_lt=-F('baz')) issue is that it
>>> violates the principle of least surprise: it will be accepted silently and
>>> do something that nobody could expect unless they know a bit about the
>>> internals. However, I think having some special case code in filter(),
>>> annotate() and anything else that takes expressions would be OK. Provided
>>> it throws some kind of exception, I think it resolves my concern.
>>>
>>> I'll go ahead and try to implement this using __neg__() to invert the
>>> ordering.
>>>
>>> Tim
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Django developers" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to django-developers+unsubscr...@googlegroups.com.
>>> To post to this group, send email to django-developers@googlegroups.com.
>>> Visit this group at http://groups.google.com/group/django-developers.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/django-developers/20cd8bd0-9d5d-4ed3-9748-1412188e6726%40googlegroups.com
>>> 
>>> .
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> You received this message because you are subscribed to the Google Groups
>> "Django developers" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to django-developers+unsubscr...@googlegroups.com.
>> To post to this group, send email to django-developers@googlegroups.com.
>> Visit this group at http://groups.google.com/group/django-developers.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-developers/CALuYSZVYnXHapfvf5SwPJxLYkxiv%3DTPyJg2XYGFVhCPSyc7Fgw%40mail.gmail.com
>> 
>> .
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CAGdCwBuHBtQLsVEeftfZAVrx6hdZSvz9ED%3DMmjZvyg%2B--%3D6moQ%40mail.gmail.com
> 
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALuYSZX20zM5nvz%3DQVXShu4wR8_QgropHgjR_8ZxoRbcSfxaxQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Michael Manfre
Each expression must be able to define it's own ordering because order_by
allows you to define a sort based upon multiple expressions.


On Mon, Jun 9, 2014 at 4:00 PM, Daniel Moisset 
wrote:

> I see everyone trying to put the direction (ascending vs decending) inside
> the expression, while it's actually a property of the ordering clause.
> Wouldn't it make more sense and avoid ambiguities to do:
>
> qs.order_by(..., descending=True)
>
> ?
>
> Then you can add functions (and even a __neg__ operator to fields mapped
> to SQL unary minus) and still have a clear separation of functions vs order
> direction.
>
> D.
>
>
>
> On Mon, Jun 9, 2014 at 4:44 PM, Tim Martin  wrote:
>
>> My concern about the filter(foobar_lt=-F('baz')) issue is that it
>> violates the principle of least surprise: it will be accepted silently and
>> do something that nobody could expect unless they know a bit about the
>> internals. However, I think having some special case code in filter(),
>> annotate() and anything else that takes expressions would be OK. Provided
>> it throws some kind of exception, I think it resolves my concern.
>>
>> I'll go ahead and try to implement this using __neg__() to invert the
>> ordering.
>>
>> Tim
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Django developers" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to django-developers+unsubscr...@googlegroups.com.
>> To post to this group, send email to django-developers@googlegroups.com.
>> Visit this group at http://groups.google.com/group/django-developers.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-developers/20cd8bd0-9d5d-4ed3-9748-1412188e6726%40googlegroups.com
>> 
>> .
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/CALuYSZVYnXHapfvf5SwPJxLYkxiv%3DTPyJg2XYGFVhCPSyc7Fgw%40mail.gmail.com
> 
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAGdCwBuHBtQLsVEeftfZAVrx6hdZSvz9ED%3DMmjZvyg%2B--%3D6moQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Daniel Moisset
I see everyone trying to put the direction (ascending vs decending) inside
the expression, while it's actually a property of the ordering clause.
Wouldn't it make more sense and avoid ambiguities to do:

qs.order_by(..., descending=True)

?

Then you can add functions (and even a __neg__ operator to fields mapped to
SQL unary minus) and still have a clear separation of functions vs order
direction.

D.



On Mon, Jun 9, 2014 at 4:44 PM, Tim Martin  wrote:

> My concern about the filter(foobar_lt=-F('baz')) issue is that it
> violates the principle of least surprise: it will be accepted silently and
> do something that nobody could expect unless they know a bit about the
> internals. However, I think having some special case code in filter(),
> annotate() and anything else that takes expressions would be OK. Provided
> it throws some kind of exception, I think it resolves my concern.
>
> I'll go ahead and try to implement this using __neg__() to invert the
> ordering.
>
> Tim
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/20cd8bd0-9d5d-4ed3-9748-1412188e6726%40googlegroups.com
> 
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CALuYSZVYnXHapfvf5SwPJxLYkxiv%3DTPyJg2XYGFVhCPSyc7Fgw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Tim Martin
My concern about the filter(foobar_lt=-F('baz')) issue is that it violates 
the principle of least surprise: it will be accepted silently and do 
something that nobody could expect unless they know a bit about the 
internals. However, I think having some special case code in filter(), 
annotate() and anything else that takes expressions would be OK. Provided 
it throws some kind of exception, I think it resolves my concern.

I'll go ahead and try to implement this using __neg__() to invert the 
ordering.

Tim

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/20cd8bd0-9d5d-4ed3-9748-1412188e6726%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Josh Smeaton
The parens definitely would work for __neg__, and as for the output_type 
problem, it's only an issue when mixing field types - but that can be 
solved by applying a matching output_type to one of the inner expressions. 
If a wrapping type isn't needed for neg, I won't introduce one to slightly 
improve the aesthetics of combinable expressions.

To answer your question about using F() as a wrapper - no that wouldn't 
work. F() must refer to an existing field by name - it doesn't wrap 
expressions.

Josh

On Monday, 9 June 2014 20:34:04 UTC+10, Anssi Kääriäinen wrote:
>
>  Could we use just F() for this, that is the examples would be:
> -F(F('field')+F('other'))
> F(F('field')+5, output_type=IntegerField())
>
> As Marc said in another post plain parentheses should be enough for the 
> first case.
>
>  - Anssi
>
> On 06/09/2014 01:19 PM, Josh Smeaton wrote:
>  
> If __neg__ is the preferred method of applying ordering then I think we 
> should prevent __neg__ from being used in the mathematical sense in the 
> other methods (filter, annotate etc). There hasn't been a need for negating 
> an expression/F() object before, and negation would only work with certain 
> expressions anyway (what would -Lower('description') even mean?). 
>
>  The problem with applying ordering to an expression still applies:
>
>  Model.objects.all().order_by( F('field')+F('other') )
>
>
>  Here, it's actually the connector (+) that is the outer-most level, so 
> there's no opportunity to apply ordering to any of the expressions. I've 
> found a similar problem with trying to apply an `output_type` to 
> expressions that are joined by a connector. I think the solution is to 
> introduce a new type that simply wraps another expression for the purposes 
> of mutation.
>
>  Model.objects.all().order_by( -Wrap(F('field')+F('other')) )
>
>  Model.objects.annotate( Wrap(F('field')+5, output_type=IntegerField()) )
>
>
>  But I'd be interested in hearing alternatives.
>
>  Josh 
>
> On Monday, 9 June 2014 20:01:18 UTC+10, Anssi Kääriäinen wrote: 
>>
>>  Using __neg__ for ordering seems like a good approach to me. I don't 
>> like F('-field') that much, if -F('field') works, then F('-field') is 
>> duplicate API for the exact same thing.
>>
>> The only problem with -F('field') is that there might be situations where 
>> ORDER BY -field ASC gives different results than ORDER BY field DESC. I am 
>> not sure if any such thing exists (maybe null handling?), but if so, and if 
>> we also add support for __neq__ for somecol__lt=-F('field'), then users 
>> might get unexpected results from .order_by(-F('field')). OTOH if we 
>> document that '-' means DESC ordering when used at outermost level in 
>> .order_by(), the API is hopefully clear enough.
>>
>>  - Anssi
>>
>> On 06/09/2014 09:33 AM, Marc Tamlyn wrote:
>>  
>> Agreed. It's worth noting that we could have a `Desc` operator for 
>> awkward edge cases where __neg__ doesn't work well, and the default 
>> implementation of __neg__ just returns Desc(self). I've not completely 
>> considered all the possible implications here, just throwing the idea 
>> around.
>>
>>
>> On 9 June 2014 01:53, Josh Smeaton  wrote:
>>
>>>  > That sounds like a workable approach. If I'm understanding right, 
>>> this means putting the ordering flag on the ExpressionNode class so that 
>>> all nodes will have this whether or not they are to be used in an ordering 
>>> context? 
>>>
>>>  Yes, that had been what I was thinking, based upon the implementation 
>>> of PeeWee ( 
>>> https://github.com/coleifer/peewee/blob/master/peewee.py#L292 ). At 
>>> first it doesn't seem very nice; having an expression containing properties 
>>> regarding ordering or even aggregates (like the current is_aggregate). But 
>>> in my experience it has turned out to be the nicest place to put that 
>>> information, that doesn't infect a large number of components. "An 
>>> expression can be ordered" makes sense.
>>>  
>>>  > My only reservation about this when combined with __neg__ is that it 
>>> means that certain mathematical expressions will behave oddly
>>>
>>>  __neg__ isn't currently supported on expressions, so it has no current 
>>> meaning. It could be used in the mathematical context though in the future, 
>>> and would make sense.
>>>  
>>>  > I think supporting this gives lots of potential problems without 
>>> much in the way of gain. Even the "correct" form Coalesce('-title', 
>>> '-description') just looks odd to me. The DESC modifier applies to the 
>>> expression as a whole, not to any one field within it
>>>
>>>  Totally agree. Ordering applies to the expression, not any one node 
>>> within that expression. So we need to figure out how best to support:
>>>
>>>  .order_by( F('field_a')+F('field_b') )
>>>
>>>
>>>  You can't apply ordering to field_a or field_b, because the returned 
>>> Expression is actually `+ (field_a, field_b)`. Considering that, a wrapping 
>>> `Desc(expression)` probably makes a 

Re: Support for function application in ORDER BY

2014-06-09 Thread Anssi Kääriäinen

Could we use just F() for this, that is the examples would be:
-F(F('field')+F('other'))
F(F('field')+5, output_type=IntegerField())

As Marc said in another post plain parentheses should be enough for the 
first case.


 - Anssi

On 06/09/2014 01:19 PM, Josh Smeaton wrote:
If __neg__ is the preferred method of applying ordering then I think 
we should prevent __neg__ from being used in the mathematical sense in 
the other methods (filter, annotate etc). There hasn't been a need for 
negating an expression/F() object before, and negation would only work 
with certain expressions anyway (what would -Lower('description') even 
mean?).


The problem with applying ordering to an expression still applies:

Model.objects.all().order_by( F('field')+F('other') )


Here, it's actually the connector (+) that is the outer-most level, so 
there's no opportunity to apply ordering to any of the expressions. 
I've found a similar problem with trying to apply an `output_type` to 
expressions that are joined by a connector. I think the solution is to 
introduce a new type that simply wraps another expression for the 
purposes of mutation.


Model.objects.all().order_by( -Wrap(F('field')+F('other')) )

Model.objects.annotate( Wrap(F('field')+5,
output_type=IntegerField()) )


But I'd be interested in hearing alternatives.

Josh

On Monday, 9 June 2014 20:01:18 UTC+10, Anssi Kääriäinen wrote:

Using __neg__ for ordering seems like a good approach to me. I
don't like F('-field') that much, if -F('field') works, then
F('-field') is duplicate API for the exact same thing.

The only problem with -F('field') is that there might be
situations where ORDER BY -field ASC gives different results than
ORDER BY field DESC. I am not sure if any such thing exists (maybe
null handling?), but if so, and if we also add support for __neq__
for somecol__lt=-F('field'), then users might get unexpected
results from .order_by(-F('field')). OTOH if we document that '-'
means DESC ordering when used at outermost level in .order_by(),
the API is hopefully clear enough.

 - Anssi

On 06/09/2014 09:33 AM, Marc Tamlyn wrote:

Agreed. It's worth noting that we could have a `Desc` operator
for awkward edge cases where __neg__ doesn't work well, and the
default implementation of __neg__ just returns Desc(self). I've
not completely considered all the possible implications here,
just throwing the idea around.


On 9 June 2014 01:53, Josh Smeaton  wrote:

> That sounds like a workable approach. If I'm understanding
right, this means putting the ordering flag on the
ExpressionNode class so that all nodes will have this whether
or not they are to be used in an ordering context?

Yes, that had been what I was thinking, based upon the
implementation of PeeWee (
https://github.com/coleifer/peewee/blob/master/peewee.py#L292

). At first it doesn't seem very nice; having an expression
containing properties regarding ordering or even aggregates
(like the current is_aggregate). But in my experience it has
turned out to be the nicest place to put that information,
that doesn't infect a large number of components. "An
expression can be ordered" makes sense.

> My only reservation about this when combined with __neg__
is that it means that certain mathematical expressions will
behave oddly

__neg__ isn't currently supported on expressions, so it has
no current meaning. It could be used in the mathematical
context though in the future, and would make sense.

> I think supporting this gives lots of potential problems
without much in the way of gain. Even the "correct" form
Coalesce('-title', '-description') just looks odd to me. The
DESC modifier applies to the expression as a whole, not to
any one field within it

Totally agree. Ordering applies to the expression, not any
one node within that expression. So we need to figure out how
best to support:

.order_by( F('field_a')+F('field_b') )


You can't apply ordering to field_a or field_b, because the
returned Expression is actually `+ (field_a, field_b)`.
Considering that, a wrapping `Desc(expression)` probably
makes a lot of sense, but has the following problems:

1. The syntax is somewhat ugly, but fits with the theme of
composable expressions.
2. If `Desc()` is just another expression, you'd need to
prevent it from being used in an `inner` context. It can only
be a wrapper. I think documenting this limitation is fine -
but if there was a way to throw a useful error (rather than
the database error that would surely 

Re: Support for function application in ORDER BY

2014-06-09 Thread Marc Tamlyn
For this example:
Model.objects.all().order_by( -Wrap(F('field')+F('other')) )

does just the brackets not work? -(f + g) should do f + g (returning some
object) and then negate the result. This doesn't solve your output type
issue. If it doesn't python's wrong ;)

Marc


On 9 June 2014 11:19, Josh Smeaton  wrote:

> If __neg__ is the preferred method of applying ordering then I think we
> should prevent __neg__ from being used in the mathematical sense in the
> other methods (filter, annotate etc). There hasn't been a need for negating
> an expression/F() object before, and negation would only work with certain
> expressions anyway (what would -Lower('description') even mean?).
>
> The problem with applying ordering to an expression still applies:
>
> Model.objects.all().order_by( F('field')+F('other') )
>
>
> Here, it's actually the connector (+) that is the outer-most level, so
> there's no opportunity to apply ordering to any of the expressions. I've
> found a similar problem with trying to apply an `output_type` to
> expressions that are joined by a connector. I think the solution is to
> introduce a new type that simply wraps another expression for the purposes
> of mutation.
>
> Model.objects.all().order_by( -Wrap(F('field')+F('other')) )
>
> Model.objects.annotate( Wrap(F('field')+5, output_type=IntegerField()) )
>
>
> But I'd be interested in hearing alternatives.
>
> Josh
>
> On Monday, 9 June 2014 20:01:18 UTC+10, Anssi Kääriäinen wrote:
>
>>  Using __neg__ for ordering seems like a good approach to me. I don't
>> like F('-field') that much, if -F('field') works, then F('-field') is
>> duplicate API for the exact same thing.
>>
>> The only problem with -F('field') is that there might be situations where
>> ORDER BY -field ASC gives different results than ORDER BY field DESC. I am
>> not sure if any such thing exists (maybe null handling?), but if so, and if
>> we also add support for __neq__ for somecol__lt=-F('field'), then users
>> might get unexpected results from .order_by(-F('field')). OTOH if we
>> document that '-' means DESC ordering when used at outermost level in
>> .order_by(), the API is hopefully clear enough.
>>
>>  - Anssi
>>
>> On 06/09/2014 09:33 AM, Marc Tamlyn wrote:
>>
>> Agreed. It's worth noting that we could have a `Desc` operator for
>> awkward edge cases where __neg__ doesn't work well, and the default
>> implementation of __neg__ just returns Desc(self). I've not completely
>> considered all the possible implications here, just throwing the idea
>> around.
>>
>>
>> On 9 June 2014 01:53, Josh Smeaton  wrote:
>>
>>>  > That sounds like a workable approach. If I'm understanding right,
>>> this means putting the ordering flag on the ExpressionNode class so that
>>> all nodes will have this whether or not they are to be used in an ordering
>>> context?
>>>
>>>  Yes, that had been what I was thinking, based upon the implementation
>>> of PeeWee ( https://github.com/coleifer/peewee/blob/master/peewee.py#
>>> L292 ). At first it doesn't seem very nice; having an expression
>>> containing properties regarding ordering or even aggregates (like the
>>> current is_aggregate). But in my experience it has turned out to be the
>>> nicest place to put that information, that doesn't infect a large number of
>>> components. "An expression can be ordered" makes sense.
>>>
>>>  > My only reservation about this when combined with __neg__ is that it
>>> means that certain mathematical expressions will behave oddly
>>>
>>>  __neg__ isn't currently supported on expressions, so it has no current
>>> meaning. It could be used in the mathematical context though in the future,
>>> and would make sense.
>>>
>>>  > I think supporting this gives lots of potential problems without
>>> much in the way of gain. Even the "correct" form Coalesce('-title',
>>> '-description') just looks odd to me. The DESC modifier applies to the
>>> expression as a whole, not to any one field within it
>>>
>>>  Totally agree. Ordering applies to the expression, not any one node
>>> within that expression. So we need to figure out how best to support:
>>>
>>>  .order_by( F('field_a')+F('field_b') )
>>>
>>>
>>>  You can't apply ordering to field_a or field_b, because the returned
>>> Expression is actually `+ (field_a, field_b)`. Considering that, a wrapping
>>> `Desc(expression)` probably makes a lot of sense, but has the following
>>> problems:
>>>
>>>  1. The syntax is somewhat ugly, but fits with the theme of composable
>>> expressions.
>>> 2. If `Desc()` is just another expression, you'd need to prevent it from
>>> being used in an `inner` context. It can only be a wrapper. I think
>>> documenting this limitation is fine - but if there was a way to throw a
>>> useful error (rather than the database error that would surely follow),
>>> it'd be nice.
>>> 3. order_by(F('-field_a')) wouldn't be possible - there's no way for the
>>> `F()` to push the `Desc()` to the top of the 

Re: Support for function application in ORDER BY

2014-06-09 Thread Josh Smeaton
If __neg__ is the preferred method of applying ordering then I think we 
should prevent __neg__ from being used in the mathematical sense in the 
other methods (filter, annotate etc). There hasn't been a need for negating 
an expression/F() object before, and negation would only work with certain 
expressions anyway (what would -Lower('description') even mean?).

The problem with applying ordering to an expression still applies:

Model.objects.all().order_by( F('field')+F('other') )


Here, it's actually the connector (+) that is the outer-most level, so 
there's no opportunity to apply ordering to any of the expressions. I've 
found a similar problem with trying to apply an `output_type` to 
expressions that are joined by a connector. I think the solution is to 
introduce a new type that simply wraps another expression for the purposes 
of mutation.

Model.objects.all().order_by( -Wrap(F('field')+F('other')) )

Model.objects.annotate( Wrap(F('field')+5, output_type=IntegerField()) )


But I'd be interested in hearing alternatives.

Josh 

On Monday, 9 June 2014 20:01:18 UTC+10, Anssi Kääriäinen wrote:
>
>  Using __neg__ for ordering seems like a good approach to me. I don't 
> like F('-field') that much, if -F('field') works, then F('-field') is 
> duplicate API for the exact same thing.
>
> The only problem with -F('field') is that there might be situations where 
> ORDER BY -field ASC gives different results than ORDER BY field DESC. I am 
> not sure if any such thing exists (maybe null handling?), but if so, and if 
> we also add support for __neq__ for somecol__lt=-F('field'), then users 
> might get unexpected results from .order_by(-F('field')). OTOH if we 
> document that '-' means DESC ordering when used at outermost level in 
> .order_by(), the API is hopefully clear enough.
>
>  - Anssi
>
> On 06/09/2014 09:33 AM, Marc Tamlyn wrote:
>  
> Agreed. It's worth noting that we could have a `Desc` operator for awkward 
> edge cases where __neg__ doesn't work well, and the default implementation 
> of __neg__ just returns Desc(self). I've not completely considered all the 
> possible implications here, just throwing the idea around.
>
>
> On 9 June 2014 01:53, Josh Smeaton  
> wrote:
>
>>  > That sounds like a workable approach. If I'm understanding right, 
>> this means putting the ordering flag on the ExpressionNode class so that 
>> all nodes will have this whether or not they are to be used in an ordering 
>> context? 
>>
>>  Yes, that had been what I was thinking, based upon the implementation 
>> of PeeWee ( https://github.com/coleifer/peewee/blob/master/peewee.py#L292 
>> ). At first it doesn't seem very nice; having an expression containing 
>> properties regarding ordering or even aggregates (like the current 
>> is_aggregate). But in my experience it has turned out to be the nicest 
>> place to put that information, that doesn't infect a large number of 
>> components. "An expression can be ordered" makes sense.
>>  
>>  > My only reservation about this when combined with __neg__ is that it 
>> means that certain mathematical expressions will behave oddly
>>
>>  __neg__ isn't currently supported on expressions, so it has no current 
>> meaning. It could be used in the mathematical context though in the future, 
>> and would make sense.
>>  
>>  > I think supporting this gives lots of potential problems without much 
>> in the way of gain. Even the "correct" form Coalesce('-title', 
>> '-description') just looks odd to me. The DESC modifier applies to the 
>> expression as a whole, not to any one field within it
>>
>>  Totally agree. Ordering applies to the expression, not any one node 
>> within that expression. So we need to figure out how best to support:
>>
>>  .order_by( F('field_a')+F('field_b') )
>>
>>
>>  You can't apply ordering to field_a or field_b, because the returned 
>> Expression is actually `+ (field_a, field_b)`. Considering that, a wrapping 
>> `Desc(expression)` probably makes a lot of sense, but has the following 
>> problems:
>>
>>  1. The syntax is somewhat ugly, but fits with the theme of composable 
>> expressions.
>> 2. If `Desc()` is just another expression, you'd need to prevent it from 
>> being used in an `inner` context. It can only be a wrapper. I think 
>> documenting this limitation is fine - but if there was a way to throw a 
>> useful error (rather than the database error that would surely follow), 
>> it'd be nice.
>> 3. order_by(F('-field_a')) wouldn't be possible - there's no way for the 
>> `F()` to push the `Desc()` to the top of the tree. Since this isn't already 
>> supported anyway, I don't think it's that big of a deal.
>> 4. order_by('-field_a') should produce: Desc(F('field_a')), but I think 
>> that'd be very easy. Expressions should be the only supported API for 
>> order_by, except a string referencing a field (like it is now) that is 
>> internally converted to an Expression. I do the same thing with Aggregates 
>> right 

Re: Support for function application in ORDER BY

2014-06-09 Thread Anssi Kääriäinen
Using __neg__ for ordering seems like a good approach to me. I don't 
like F('-field') that much, if -F('field') works, then F('-field') is 
duplicate API for the exact same thing.


The only problem with -F('field') is that there might be situations 
where ORDER BY -field ASC gives different results than ORDER BY field 
DESC. I am not sure if any such thing exists (maybe null handling?), but 
if so, and if we also add support for __neq__ for 
somecol__lt=-F('field'), then users might get unexpected results from 
.order_by(-F('field')). OTOH if we document that '-' means DESC ordering 
when used at outermost level in .order_by(), the API is hopefully clear 
enough.


 - Anssi

On 06/09/2014 09:33 AM, Marc Tamlyn wrote:
Agreed. It's worth noting that we could have a `Desc` operator for 
awkward edge cases where __neg__ doesn't work well, and the default 
implementation of __neg__ just returns Desc(self). I've not completely 
considered all the possible implications here, just throwing the idea 
around.



On 9 June 2014 01:53, Josh Smeaton > wrote:


> That sounds like a workable approach. If I'm understanding
right, this means putting the ordering flag on the ExpressionNode
class so that all nodes will have this whether or not they are to
be used in an ordering context?

Yes, that had been what I was thinking, based upon the
implementation of PeeWee (
https://github.com/coleifer/peewee/blob/master/peewee.py#L292 ).
At first it doesn't seem very nice; having an expression
containing properties regarding ordering or even aggregates (like
the current is_aggregate). But in my experience it has turned out
to be the nicest place to put that information, that doesn't
infect a large number of components. "An expression can be
ordered" makes sense.

> My only reservation about this when combined with __neg__ is
that it means that certain mathematical expressions will behave oddly

__neg__ isn't currently supported on expressions, so it has no
current meaning. It could be used in the mathematical context
though in the future, and would make sense.

> I think supporting this gives lots of potential problems without
much in the way of gain. Even the "correct" form
Coalesce('-title', '-description') just looks odd to me. The DESC
modifier applies to the expression as a whole, not to any one
field within it

Totally agree. Ordering applies to the expression, not any one
node within that expression. So we need to figure out how best to
support:

.order_by( F('field_a')+F('field_b') )


You can't apply ordering to field_a or field_b, because the
returned Expression is actually `+ (field_a, field_b)`.
Considering that, a wrapping `Desc(expression)` probably makes a
lot of sense, but has the following problems:

1. The syntax is somewhat ugly, but fits with the theme of
composable expressions.
2. If `Desc()` is just another expression, you'd need to prevent
it from being used in an `inner` context. It can only be a
wrapper. I think documenting this limitation is fine - but if
there was a way to throw a useful error (rather than the database
error that would surely follow), it'd be nice.
3. order_by(F('-field_a')) wouldn't be possible - there's no way
for the `F()` to push the `Desc()` to the top of the tree. Since
this isn't already supported anyway, I don't think it's that big
of a deal.
4. order_by('-field_a') should produce: Desc(F('field_a')), but I
think that'd be very easy. Expressions should be the only
supported API for order_by, except a string referencing a field
(like it is now) that is internally converted to an Expression. I
do the same thing with Aggregates right now.

> An alternative is to use ~ instead of - meaning inverse instead
of negative. This might be more appropriate (but then is
~LowerCase not UpperCase?).

I don't think anyone would ever expect ~LowerCase to mean
UpperCase, but it is still somewhat confusing syntax. ~ is mostly
used in Q() objects to mean NOT, and could be very confusing. We
also run into similar issues with the `order_by( F()+F() )` use
case above - applying a unary operator to either of those objects
won't actually result in any ordering being applied.

Josh

On Monday, 9 June 2014 02:07:42 UTC+10, Tim Martin wrote:


On Sunday, 8 June 2014 13:24:01 UTC+1, Josh Smeaton wrote:

I've thought about this previously, and what I had in mind
was:

- Expressions should support an ordering parameter of some
kind in the constructor, and save it to an ordering
property. Default to ASC
- If we go with Marc's suggestion, the __neg__ can set the
above property. This would look very consistent with the

Modify get_or_create() to use field lookups parameters for values

2014-06-09 Thread Patrick Bregman
Hi all,

First of, I'm new to this list so please tell me if there's something that 
can be done better. It's the best way to learn for me ;)

Recently I've been doing some reworking of an old (think Django 1.1 or 1.2) 
webapp of mine into the latest and greatest of Django. In the process I 
modified some models, and thought that *get_or_create* would be perfect to 
replace boring try / except cases. Except that it didn't really work as 
planned. I tried to do a *get_or_create(name__iexact=value, 
defaults={'slug': slugify(value)})*. I expected this to be smart enough to 
know that it should fill the field *name* based on the *name__iexact* 
parameter. Apparently it isn't :) In this case you'd need to add a 
definition for *name* to the *defaults* dict to get the value into the 
newly created model. I'm not sure, but I personally think this shouldn't be 
that hard to fix. It's basically checking (and removing) known field 
lookups or simply everything after a double underscore, and using that as a 
field name. Or at least, that's my view on it.

The big question is:
1. Is this behavior that exotic that I'm the first one to notice, or did I 
do a wrong search on Google?
2. Would this indeed be as easy (or comparably easy) as I think? 
3. Is this behavior we actually want in Django?

If the answer to 2 and 3 are yes, I'll look into giving it a try to making 
a patch for this myself.

Regards,
Patrick Bregman

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/a02fbaf8-441d-48d0-8787-965c4efa46e6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Proposal: variable argument lists for templatetags, in templates.

2014-06-09 Thread Przemek Czerkas
Hi,

In this ticket https://code.djangoproject.com/ticket/13956 (Indefinite args 
for simpletags and inclusion tags) a support for *args and **kwargs for 
simple_tag, inclusion_tag and assignment_tag was added.

I think that one piece is still missing. How about allowing to pass 
*args/**kwargs to templatetag arguments:

{% some_tag [positional_args] [named_args] *args **kwargs %}

where args is a list, kwargs is a dict?

With this new syntax, the resolution of variable arguments would had to be 
moved to the render() phase, as well as some of the argument checking (e.g. 
{% with kwargs %} case for empty kwargs).

What do you think?

Regards,
Przemek Czerkas

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/26414649-8562-44a4-99f8-d456fe0028d3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Support for function application in ORDER BY

2014-06-09 Thread Marc Tamlyn
Agreed. It's worth noting that we could have a `Desc` operator for awkward
edge cases where __neg__ doesn't work well, and the default implementation
of __neg__ just returns Desc(self). I've not completely considered all the
possible implications here, just throwing the idea around.


On 9 June 2014 01:53, Josh Smeaton  wrote:

> > That sounds like a workable approach. If I'm understanding right, this
> means putting the ordering flag on the ExpressionNode class so that all
> nodes will have this whether or not they are to be used in an ordering
> context?
>
> Yes, that had been what I was thinking, based upon the implementation of
> PeeWee ( https://github.com/coleifer/peewee/blob/master/peewee.py#L292 ).
> At first it doesn't seem very nice; having an expression containing
> properties regarding ordering or even aggregates (like the current
> is_aggregate). But in my experience it has turned out to be the nicest
> place to put that information, that doesn't infect a large number of
> components. "An expression can be ordered" makes sense.
>
> > My only reservation about this when combined with __neg__ is that it
> means that certain mathematical expressions will behave oddly
>
> __neg__ isn't currently supported on expressions, so it has no current
> meaning. It could be used in the mathematical context though in the future,
> and would make sense.
>
> > I think supporting this gives lots of potential problems without much in
> the way of gain. Even the "correct" form Coalesce('-title',
> '-description') just looks odd to me. The DESC modifier applies to the
> expression as a whole, not to any one field within it
>
> Totally agree. Ordering applies to the expression, not any one node within
> that expression. So we need to figure out how best to support:
>
> .order_by( F('field_a')+F('field_b') )
>
>
> You can't apply ordering to field_a or field_b, because the returned
> Expression is actually `+ (field_a, field_b)`. Considering that, a wrapping
> `Desc(expression)` probably makes a lot of sense, but has the following
> problems:
>
> 1. The syntax is somewhat ugly, but fits with the theme of composable
> expressions.
> 2. If `Desc()` is just another expression, you'd need to prevent it from
> being used in an `inner` context. It can only be a wrapper. I think
> documenting this limitation is fine - but if there was a way to throw a
> useful error (rather than the database error that would surely follow),
> it'd be nice.
> 3. order_by(F('-field_a')) wouldn't be possible - there's no way for the
> `F()` to push the `Desc()` to the top of the tree. Since this isn't already
> supported anyway, I don't think it's that big of a deal.
> 4. order_by('-field_a') should produce: Desc(F('field_a')), but I think
> that'd be very easy. Expressions should be the only supported API for
> order_by, except a string referencing a field (like it is now) that is
> internally converted to an Expression. I do the same thing with Aggregates
> right now.
>
> > An alternative is to use ~ instead of - meaning inverse instead of
> negative. This might be more appropriate (but then is ~LowerCase not
> UpperCase?).
>
> I don't think anyone would ever expect ~LowerCase to mean UpperCase, but
> it is still somewhat confusing syntax. ~ is mostly used in Q() objects to
> mean NOT, and could be very confusing. We also run into similar issues with
> the `order_by( F()+F() )` use case above - applying a unary operator to
> either of those objects won't actually result in any ordering being applied.
>
> Josh
>
> On Monday, 9 June 2014 02:07:42 UTC+10, Tim Martin wrote:
>>
>>
>> On Sunday, 8 June 2014 13:24:01 UTC+1, Josh Smeaton wrote:
>>>
>>> I've thought about this previously, and what I had in mind was:
>>>
>>> - Expressions should support an ordering parameter of some kind in the
>>> constructor, and save it to an ordering property. Default to ASC
>>> - If we go with Marc's suggestion, the __neg__ can set the above
>>> property. This would look very consistent with the existing ordering api.
>>> - F() objects should parse their field argument, and internally set
>>> their ordering attribute appropriately -> F('-title') should strip the `-`
>>> and set a DESC ordering.
>>> - Since expressions can be nested, you can't return ASC/DESC from the
>>> as_sql() method, otherwise you'd end up with weirdness like: 
>>> Coalesce(field_a
>>> ASC, field_b ASC) instead of Coalesce(field_a, field_b) ASC. Therefore,
>>> the order_by machinery should call a `get_ordering()` (or something named
>>> similarly) and generate the ASC/DESC token accordingly.
>>>
>>
>> That sounds like a workable approach. If I'm understanding right, this
>> means putting the ordering flag on the ExpressionNode class so that all
>> nodes will have this whether or not they are to be used in an ordering
>> context?
>>
>> My only reservation about this when combined with __neg__ is that it
>> means that certain mathematical expressions will behave oddly.