I thought I'd post my solution in case anyone faces a similar situation. Problem: I am using an intermediate model (R) to represent a relationship between models Location and Thread. Given an instance of Location, say x, I want the property x.threads to return a QuerySet containing all of the related thread instances. This requires spanning the R relationship, since I don't want instances of R. This is nice because it is convenient, it hides implementation, and is a lazy queryset.
Solution: I wrote a function that writes a ".extra()" query. I couldn't find an easier way. Anyway its the first time I used .extra and ._meta, so I'm not sure how reliable it is. I would appreciate any feedback matter :) Its not entirely general yet... def span_table(sourceField, targetField, relnModel, sourceModel, targetModel, moreTables=[], moreWhere=[], moreParams=[]): # moreTables, moreWhere, and moreParams let you restrict # on fields stored in the intermediate table relnTable = relnModel._meta.db_table targetTable = targetModel._meta.db_table targetPkColumn = targetModel._meta.pk.column sourcePkAttr = sourceModel._meta.pk.attname tables = [ relnTable ] + moreTables where = [ '%s.%s_id = %s' % (relnTable, sourceField, '%s'), '%s.%s_id = %s.%s' % (relnTable, targetField, targetTable, targetPkColumn) ] + moreWhere def f(sourceObject, **kw): params = [ getattr( sourceObject, sourcePkAttr ) ] + moreParams # assumes the manager is objects... return targetModel.objects.filter(**kw).extra( tables=tables, where=where, params=params ) return f class Thread(models.model): pass class Location(models.model): pass class LocationThread(models.model): thread = models.ForeignKey( Thread ) location = models.ForeignKey( Location) # using the function Location.threads = property( span_table('location', 'thread', LocationThread, Location, Thread) ) so now myLocation.threads returns a query set Best, - Steve On 10/16/06, Steve Wedig <[EMAIL PROTECTED]> wrote: > Alrighty, I've pulled out the relationships into separate separate > models, as shown below. This correctly represents the information. > However, I would like to work with the sets of related threads > directly, rather than always traversing the intermediate models. > > I'm not sure how to write the functions where the ???'s appear below. > I'd like to return a lazy QuerySet of threads (so basically pretending > the threads are directly related). I would appreciate any advice on > this matter... > > class Thread(models.model): # threads don't care where they are used > > class Location(models.model): > def thread_set(self): > ??? > thread_set = property(thread_set) > > class LocationThread(models.model): # m-n relationship > thread = models.ForeignKey( Thread ) > location = models.ForeignKey( Location) > > class Group(models.model): > def thread_set(self): > ??? > thread_set = property(thread_set) > > class GroupThread(models.model): # m-1 relationship > thread = models.OneToOneField( Thread ) > location = models.ForeignKey( Location) > > Thanks, > Steve > > On 10/16/06, Malcolm Tredinnick <[EMAIL PROTECTED]> wrote: > > > > On Mon, 2006-10-16 at 02:44 -0700, Steve Wedig wrote: > > > I have a thread model that I would like to reuse in multiple places. > > > So a thread should have no knowledge of where it is contained. > > > > > > I also have a group model and a location model. I would like to have > > > multple threads in a group (1-n reln between group and thread). I > > > would also like threads to appear at _multiple_ locations (so a m-n > > > reln between location and thread). > > > > > > I am wondering, what is the best way to accomplish this in django? I > > > am reasonably familiar with the generic relation mechanism, however > > > that appears to only work for 1-n relationships. Plus I don't want to > > > a thread to worry about where/how it is used/contained. > > > > A many-to-many relation is identical to two one-to-many relations put > > back-to-back. Think about how a many-to-many relation is implemented at > > the table level (whether by Django or in any database setup): you have a > > table in the middle that contains pairs of entries, one from each end of > > the many-to-many relation. > > > > So I would think you could create a many-to-many generic relation by > > having an intermediate model that is 1-n to both the thread and location > > models. All the intermediate model does is handle the connection. Note > > that I haven't actually worked out the details, but I can't think of any > > insurmountable problem. If you get stuck implementing this, sing out and > > we should be able to help. > > > > Regards, > > Malcolm > > > > > > > > > > > > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---