On 9/18/07, Russell Keith-Magee <[EMAIL PROTECTED]> wrote: > First off - I acknowledge the underlying problem (making m2m > intermediate models easier to use), and I would like to see a > solution. However, while I'm sure your propsed solution could be made > to work, I'm not sure it would be a good solution to the problem.
And I'm glad to hear opposition, it helps makes things that much cleaner. > The biggest problem with the "m2m intermediate" pattern is that it > requires you to think about an m2m relation as 'a model with a foreign > key on two other models', which while completely accurate, is not a > natural way to think about the problem (witness the large number of > users who ask for explanations of the m2m intermediate example). I admit I don't have experience with how many people ask for explanations of that pattern, but I can understand your point all the same. > The syntax you propose here aims to formalize the use of this pattern, > adding accessors on the related objects. This means that defining an > m2m relation ceases to be a simple matter of putting a field on one > model that references another model, and becomes an exposition of a > not-entirely-obvious pattern. This pattern is syntactically verbose, > and has a few edge cases which would require it to be more verbose. > > For example: consider what happens when you define a Relationship with > _three_ foreign keys. Which two get magically picked as the m2m keys? > This means that you need to add a keyword to ForeignKeys to identify > the m2m keys, or you need to add a RelationshipKey class with > validation logic to make sure that you have exactly 2 instances. I admit that this situation had crossed my mind in the previous discussion, and I had simply set it aside for the time being. Unfortuantely, I neglected to pick it back up before writing up this proposal. I wish I could say that's unlikely, but it's not even an edge case, really. In a Person-Role-Film scenario, the Role relationship could have a ForeignKey to some RoleCategory, indicating whether it's an acting role, directing, production, set design, etc. So, point taken. > > * Should something like this happen? > > If you go back into the archives to the last time you raised this > issue [1], you'll see that Jacob and I are in agreement that there is > significant room to improve the interface for m2m intermediate > classes. Well, wen I wrote "something like this" I meant "something like the design I'm proposing here". Obviously everybody wants a better way to do this, I just wasn't sure if my existing proposal was even worth considering. > > * How should the Relationship be tied to related Models? Through > > explicit ForeignKeys on the Relationship? Through a new "through" > > attribute on ManyToManyField? Something else entirely? > > The 'through' attribute has always been the suggested syntax. And I'm beginning to lean more that way myself, after some more reflection. More on that below. > > * How would add(), remove() and company reference the related models > > in a reliable fashion? > > This has always been the sticking point. However, a pretty good > solution came out of the discussion the last time this came up. Are you referring to the ManyToManyHelper I proposed recently? The discussion you linked to didn't really touch on this issue, so I figure you probably are. That proposal still has a lot of ambiguity as to which side of the relationship triggered the add(), though admittedly that's not *as* necessary. What's really necessary is having arguments to the function which are quite clear as to what they reference. I'm beginning to think that signals may indeed be the way to go here. Okay, so to go about this a little differently, here's another option, which should be more in line with the existing sentiments on the issue. class Actor(models.Model): name = models.CharField(maxlength=255) class CrewMember(models.Model): name = models.CharField(maxlength=255) class Role(models.Relationship): name = models.CharField(maxlength=255) class Film(models.Model): title = models.CharField(maxlength=255) actors = models.ManyToManyField(Actor, through=Role) crew = models.ManyToManyField(CrewMember, through=Role) This eliminates the explicit ForeignKeys, relying on the ManyToManyField's definition to specify those. As shown, this would also allow (and, in essence, encourage) relationships to be reusable. In this case, the Role relationship could be used to link two different pairs of models, with each relationship forming a separate table behind the scenes. Of course, this means that it no longer makes sense to have an inner Meta class on Role, but that was probably a bad approach anyway. The db_table can still be optionally specified the same way it is now, in ManyToManyField. Now, yes, I realize that this looks almost exactly like what you guys told me to do last time, but I think it's still worth separating Relationship from Model, so that it doesn't look like just any other model, but with some sparkly magic involved. The default manager for Relationship would probably be considerably different as well, but I haven't thought much about that yet. It would still make sense (to me) to create a full-fledged Model behind the scenes though, so that the existing model Fields can simply be passed over to that and let syncdb and company be happy with a proper Model. I think I can make signals work well, if the signal provides a few arguments. I'm think that if it sent "sender" (the Relationship), "origin" and "related" (the two models), people should be able to register functions to do just about anything. I'm not sure though, there are still some questions about how it would be registered, and whether a single function could adequately handle being called from both sides. I'm trying to stick to DRY here, but it's a tricky one. -Gul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@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-developers?hl=en -~----------~----~----~----~------~----~------~--~---