On Sat, Oct 15, 2011 at 9:52 PM, Tim Chase
<django.us...@tim.thechases.com>wrote:

> I have some gnarly AND/OR logic combining Q() objects but deep
> within the logic, I need to do a comparison of two constants.  In an ideal
> world, the logic would look something like
>
>   def age(self, age):
>     ... & Q(12=as_of.month) & ...
>
> but that's invalid python.
>
> I *can* break out this rats' nest of logic into individual
> queries, evaluate the constant expression, conditionally OR the
> logic into the tree, then reassemble all the parts.  However,
> that gets even uglier.

...

> Is there any way to include a constant comparison in a Q()?


Q objects are definitely not meant to handle that -- they have to operate on
some field in the database.

Besides, if you need to compare two constants, and you have both of them
available in python before you construct your query, then why would you want
to compare them in SQL? If the point is to include or exclude some other
conditions based on the calling parameters, then I would just use those
parameters to construct the right query to begin with.

I would think that breaking it into smaller, manageable pieces would make
the code easier to understand, rather than uglier, but that's a matter of
aesthetics, I suppose.

If you don't want to do that, then just use python to selectively include or
exclude the other Q objects (that you wanted to depend on your comparison):

Using your code as a base, I would do something like this: (I don't know if
this is correct; I get a headache trying to count all of the parentheses :)
)

 alive_q = use_as_of & (
    # dob1 >= y1
    Q(dob_year_min__gt=alive_y1) | (
    Q(dob_year_min=alive_y1) & (
      Q(dob_month=None) |
      Q(dob_month__gt=as_of.month) | (
      Q(dob_month=as_of.month) & (
        Q(dob_day=None) |
        Q(dob_day__gte=as_of.day)
        ))
      )) | (

*# MAGIC HAPPENS HERE*
*     ( Q(dob_month=1, dob_day=None) if as_of.month==12 else Q() )  |    *
*     ( Q(dob_day=1) if as_of_day==31 else Q())*
*# END MAGIC*

        ))
    ) & (
    # dob2 < y2
    Q(dob_year_max__lt=alive_y2) | (
    Q(dob_year_max=alive_y2) & (
      Q(dob_month=None) |
      Q(dob_month__lt=as_of.month) | (
      Q(dob_month=as_of.month) & (
        Q(dob_day=None) |
        Q(dob_day__lt=as_of.day)
        ))
      )) | (
    Q(dob_year_max=alive_y2+1) & (
      Q(dob_month=1) & (
        Q(dob_day=None) |
        Q(dob_day__lt=1)
      ))
     ))

-- 
Regards,
Ian Clelland
<clell...@gmail.com>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to