On Jun 2, 6:53 am, Russell Keith-Magee <[email protected]>
wrote:
> I might be missing something in the details here, but are you
> proposing here that even though there's only one FK reverse relation
> from Event to Person, there would be 2 attributes (events and
> confirmed_events) containing lists? That doesn't strike me as a good
> idea in itself -- or, at least, something that needs to be followed
> through elsewhere in the API. Introducing attributes to a model as a
> result of a prefetch_related call isn't something that has an analog
> anywhere else in the ORM, AFAICT.
The syntax is only usable in the context of prefetch_related. I was
trying to solve the problem of how to use custom managers in the
prefetch_related case. Something having the capabilities of the R-
objects would offer a solution to the prefetch_related part of the
related manager problem. The idea is not meant as a way for related
manager solution outside of the prefetch_related domain.
The R-objects try to offer an API with three options
1. The lookup path.
2. To what name to fetch the objects.
3. What objects to fetch from the related set. The R-objects offer
the most generic approach, allowing the use of custom querysets.
> Still, the R-objects are ugly. Lets throw them away from this discussion.
> If you drop the 'multiple attributes' thing, then the general problem
> you describe could be syntactically covered by:
>
> Person.objects.prefetch_related('events',
> events__locations=['confirmed','objects'])
As you said this doesn't work. Still, this doesn't work even in the
well-defined case of:
Person.objects.prefetch_related(events=['confirmed'],
events__locations=['confirmed','objects'])
The reason for this is that you can't have person.events.all() contain
only confirmed events. It will break the assumption that
p1.events.all() == p2.events.all() where p1 is fetched using queryset
with prefetch and p2 without prefetch. So, you definitely need some
way to fetch the custom related manager objects to different name than
the 'events' above.
> i.e., the events attribute is prefetch-populated with the default
> manager, but only those matching the confirmed manager would have a
> location pre-poulated. However, this would be a can of worms all of
> its own as far as implementation is concerned (probably not
> impossible, but sufficiently complex to implement and maintain that I
> would be completely comfortable saying "no, you can't do that").
>
> And that's something I'm willing to do more broadly, too.
> Prefetch_related is an optimisation. If we can find an elegant way to
> integrate non-default manager selection, then sure -- lets do it. But
> if we can only introduce non-default manager selection at the cost of
> a hideously complex API, then I'm inclined to just call it a
> limitation (albeit an unfortunate one) of the feature.
Agreed.
While writing this post I figured out one problem for the
events('confirmed') syntax. You can't use events('confirmed') in the
templates, while you can use events.confirmed.
So, another prefetch_related API idea:
People.objects.prefetch_related('events.confirmed',
'events.confirmed__locations')
Now, each people will have confirmed events prefetched and accessible
from people.events.confirmed.all(). Each confirmed event will have
locations prefetched.
I am using the '.' syntax above. Another idea is to use '__' as the
name separator. In this context the events('confirmed') syntax will
not work for the template reason mentioned above.
The above allows use of custom related managers in prefetch_related,
but nothing else. Custom related managers allow in turn the use of any
queryset you want, though it does not allow defining the querysets
dynamically. You could extend the syntax to:
People.objects.prefetch_related(
('events.unconfirmed', Events.objects.filter(confirmed=False)),
('events.unconfirmed__locations.ordered',
Locations.objects.order_by('-name'))
)
if needed later on.
- Anssi
--
You received this message because you are subscribed to the Google Groups
"Django developers" 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-developers?hl=en.