H'ok, got this working. First off, I had a brain hiccup: my model was one-to-many (the actual model is more complicated than my Book example; I just used the Book to illustrate my point).
What I ended up doing was basically what you suggested to do using Django's ORM: I ran two queries, one for Books and one for Authors. Then I looped through and sewed them all together. That was a fairly simple solution (which is the best kind), and I thank you for pointing it out to me! On Sep 1, 7:40 pm, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: > On Sep 2, 2008, at 9:52 AM,MrJogowrote: > > > > > I read that post, and now have a general idea of what to do, but I'm > > still confused on the specifics. It doesn't help that my SQL is VERY > > rusty. > > I'm really not the one to be walking you through this, since my own > success was a bit of a fluke, but maybe I can nudge things in the > right direction. > > > > > Am I supposed to use cursor.execute() to do the INITIAL lookup? That > > is, instead of calling a filter, or whatnot, on each book entry, I do > > a cursor.execute that gets the books I want AND the related living > > authors in one fell swoop? Do I set that up as a custom Manager? > > The way I did it was one query for the base queryset, and then one > cursor.execute() that pulled out the extra info I wanted to attach to > each queryset object. You certainly could do one cursor.execute() to > retrieve the entire query, but then you'd have to work with raw data, > not nice python objects. > > Come to think of it, you might not even want to use cursor.execute(). > I did that because all I wanted was an extra list of pks, not full > model instances. If you want to use the living authors as full > instances (ie call methods on them), then you could do this all with > Django's ORM: one query of books with living authors, one query of > living authors, then python to attach the two. > > Whether you set it up as custom manager or not mostly depends on how > often you expect to be using this particular query. More than once or > twice, and you might as well make it a manager method. > > > What would be the SQL for that? My model does not create an in between > > table (such as appname_book_authors). > > How do I append my results to a queryset? > > It depends on your table set up, but the basic concept is looping over > books, and giving each book a new attribute 'living_authors' which is > a list of Author instances. > > The model definitions you posted earlier are a little odd, you say > you've got a M2M relationship between books and author, but actually > your Author has a foreign key to Book – ie, each Author can only have > written one book. If it were a M2M relationship, you'd probably put an > M2M 'authors' field on Book, and leave Author alone. That would create > the appname_book_authors table... > > Let me know if the model structure you posted is really the one you > want to use, and I might be able to help with the next step... > > Yours, > Eric > > > I tried to figure these things out on my own, but I just couldn't wrap > > my head around it. > > > On Aug 26, 2:32 am, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: > >> On Aug 26, 2008, at 5:00 PM,MrJogowrote: > > >>> I guess I saw it as operating on a group of objects: filtering the > >>> group of authors related to my_book by is_living. I also think I got > >>> RelatedManager confused with Manager. > > >> Yaar, it can be a bit confusing. I guess what's important is to > >> remember which model you've started your query with – all queries are > >> relative to that table. I wonder if it's possibly to subclass > >> RelatedManager and add custom methods, come to think of it... > > >>> I think I can handle two db hits, although it's not optimal. I wish > >>> there was a way to get a set of data filtered on many levels (ie, > >>> only > >>> books with living authors AND only the related living authors) with > >>> one command/db hit. > > >> It will be more than two db hits if you've got to call > >> living_authors() on every book in the set! > > >> Actually I needed to do something like this recently, here's a link > >> to > >> the relevant > >> thread:http://groups.google.com/group/django-users/browse_thread/thread/9be1 > >> ... > > >> There's a lot of cruft in that thread, the basic idea is using > >> cursor.execute() to do your subqueries (selecting all living authors > >> per book), and then using pure python to attach those subqueries to > >> your larger book queryset. It's not as painful as it sounds. > > >> Lastly, there are rumors of aggregation support coming soon/already > >> here, but I'm not sure how that works (or even if it will solve these > >> kinds of problems) so will say no more... > > >> E > > >>> On Aug 26, 2:10 am, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: > >>>> On Aug 25, 2008, at 3:11 PM,MrJogowrote: > > >>>>> How do I create a custom manager for many-to-many traversal? An > >>>>> example will illustrate what I want to do better. Suppose I have > >>>>> the > >>>>> following models.py: > > >>>>> class Book(models.Model): > >>>>> title = models.CharField(max_length=100) > > >>>>> class Author(models.Model): > >>>>> books = models.ForeignKey(Book) > >>>>> name = models.CharField(max_length=100) > >>>>> is_alive = models.BooleanField() > > >>>>> This is a many-to-many relationship: a book can have multiple > >>>>> authors > >>>>> and an author can have written multiple books. > > >>>>> If I have a book object my_book, and I want to get all the > >>>>> authors, I > >>>>> do my_book.author_set.all(). How can I set up a custom manager to > >>>>> only > >>>>> get living authors of that book, so I could do something like > >>>>> my_book.livingauthor_set.all()? > > >>>> Custom managers are usually used for table-level functionality, ie > >>>> you'd make a manager method that filters or acts on a *group* of > >>>> books, not one single book. The usual thing to do when you want > >>>> something from a single object is to put a custom method on Book, > >>>> which returns living authors, like: > > >>>> def living_authors(self): > >>>> return self.author_set.filter(is_alive=True) > > >>>> What I don't know is if there's any way to keep this from making > >>>> another db hit every time you call some_book.living_authors(). > >>>> QuerySets can't be further filtered once they've been evaluated, so > >>>> using select_related() on the original Book QuerySet might not > >>>> help... > > >>>> Yours, > >>>> Eric > > >>>>> Thanks --~--~---------~--~----~------------~-------~--~----~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---