On Wed, 2007-12-26 at 05:57 -0800, tomer filiba wrote:
> i'm having a lot of trouble with order_by on foreign keys, or namely,
> ManyToMany fields.

Generally, ordering by a many-to-many field doesn't make sense. You have
a result set, each of which can have *multiple* related objects and just
because the related objects are comparable to each other doesn't imply
that a set of related objects can be compared to another set. So I doubt
that this will ever work. You would need a way to say how to order the
many-to-many sets when they are compared to each other.

> here's a simplified version of the code:
> 
> # holds info about a test (filename, etc.)
> class TestInfo(models.Model):
>     name = models.CharField(max_length=200)
>     filename = models.CharField(max_length=200, null = True)
> 
> # holds info about the execution of test (status, etc.)
> class TestResult(models.Model):
>     info = models.ForeignKey(TestInfo, related_name = "results")
>     revision = models.IntFielf()
>     status = models.CharField(max_length = 1, choices =
> STATUS_CHOICES)
> 
> # holds info about a system that is being tested.
> class SystemInfo(models.Model):
>     name = models.CharField(max_length = 100)
>     version = models.FloatField()
>     results = models.ManyToManyField(TestResult, related_name =
> "systems")
>     # a test may be run on several systems and a system
>     # may be tested by several tests, so it's a ManyToMany
> 
> let t be a TestInfo object and i want to get the latest TestResult of
> t,
> meaning, the latest revision that was executed on the latest the
> latest
> system version:
> 
> latest = t.results.order_by("-revision", "-systems__version")[0]
> 
> but trying to order by systems__version fails miserably.
> any ideas? or is it just impossible to order by manytomany fields?

Here's the reason it doesn't really make sense to do this, couched in
the terms of your example. Keep in mind that although with a few extra
bits of information about the particular problem domain, we could
construct *an* answer here, there's no general answer that will work for
all situations:

Take three SystemInfos, S1, S2, S3 and let their version fields be the
same as their number (S1.version = 1, S2.version =2, S3.version=3). Take
two TestResults, T1 and T2, both with "revision" fields set to 1 (so
sorting on revision doesn't distinguish them).

Let S1.results = [T1], S2.results=[T2], S3.results = [T1].

Finally, let's have one TestInfo, I1 and both T1.info and T2.info point
to I1. So far I have a set of objects, I1, T1, T2, S1, S2, S3 that are
consistent with your models.

Now your 't' is I1 and I1.results is [T1, T2]. T1.systems = [S1, S3] and
T2.systems = [S2]. So even if Django somehow decided that
"-systems__versions" meant to consider the sets {1, 3} for T1 and {2}
for T2, there's no canonical way to order those two sets given that we
only know how to order "floats". Are bigger sets smaller? Larger? Do we
just take the minimum element?

I suspect you might now say, "but each TestResult corresponds to a
unique TestInfo", except there's no way for Django to know that.
Similarly, we have to assume the worst case for many-to-many sets (that
there will be multiple results of differing sizes).

Sorry to be the bearer of bad news here, but this is something you'll
need to do by pulling in the results and sorting in Python (which isn't
really that big a deal ... Python is very fast at sorting even a tens of
thousands of objects at once).

Regards,
Malcolm

-- 
The early bird may get the worm, but the second mouse gets the cheese. 
http://www.pointy-stick.com/blog/


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

Reply via email to