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.