Although, I think it'd be great to have it as propsed, at some point
the OO of your ORM needs to make consessions to the SQL of your ORM. 
Which goes back to my earlier proposal.

That said...  Person.objects could be a property that returns the
Manager/Query.  In this way you could send a cacheless version of it
every time it is called, and would work for your first bit of code, as
desired.

On 1/29/06, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
>
> On 1/28/06, Luke Plant <[EMAIL PROTECTED]> wrote:
> > As Robert pointed out before, you usually don't have to worry about
> > resetting the cache, since the objects will get GC after the template
> > and views stop using them.  However, the Article.objects manager is
> > special, since it is rooted in a class, and that's going to persist,
> > isn't it?  So any iteration of Article.objects will cause the entire
> > table to be read and kept in memory.
> >
> > You could say - "if there are no 'where clause' params added, then don't
> > cache", but this wouldn't work for custom managers e.g.
> > Articles.goodarticles = Articles.objects.filter(score_gt=50), since they
> > would persist too.
> >
> > One solution would be to have managers not cache by default, but you
> > could call Articles.objects.with_cache(True) to get an instance with
> > caching turned on.  Related object lookups would always do that.
>
> I've finally wrapped my brain around this problem, and it's a tricky
> one. A common idiom is to do this in a view:
>
>     def some_view(request):
>         person_list = Person.objects
>         return render_to_response('foo/person_list', {'person_list':
> person_list})
>
> As Luke mentioned, we cannot cache the result of Person.objects,
> because the class persists. (The next time somebody does
> Person.objects, he will get the result of the cache, which is not what
> we want.)
>
> But we *do* want caching, because if we don't have it in this case, it
> will do a separate database query each time person_list is iterated
> over. That's not good, either.
>
> The goal is: Only one database query, and no persistent caching across
> accesses to Person.objects.
>
> One way to solve this problem would be to require people to use list():
>
>     def some_view(request):
>         person_list = list(Person.objects)
>         return render_to_response('foo/person_list', {'person_list':
> person_list})
>
> But that's a horrible hack, IMO, and it's would be hard to explain to
> new Django users why they'd need to do that.
>
> This comes back to the Person.objects.all() thing that I'd mentioned
> earlier. With all(), there's no strange special-case behavior.
> Person.objects.all() would return a cache-filled object, and there
> wouldn't be a need for a QuerySet to know whether it could accept
> caching or not.
>
>     def some_view(request):
>         person_list = Person.objects.all()
>         return render_to_response('foo/person_list', {'person_list':
> person_list})
>
> This would further simplify things by making a Manager's methods
> *return* QuerySets instead of having a Manager *be* a QuerySet. The
> downside is it's slightly more typing to do Person.objects.all() than
> Person.objects -- but that's the only downside I see. Thoughts?
>
> Adrian
>
> --
> Adrian Holovaty
> holovaty.com | djangoproject.com | chicagocrime.org
>

Reply via email to