I was hoping to bring up some ManyToMany enhancements at the sprint, but I didn't manage to participate after all, so they went unvoiced. Instead, I'll bring up some thoughts here and see what you guys think. I apologize in advance for the length of this post, but if you're interested in seeing M2M stuff work better, I think it's worth the read.
The more I read about what people want out of M2M fields, the more I think we need to define relationships as a separate high-level structure. I'm thinking of adding a Relationship class to the mix, which would be subclassed much like the existing Model class. This Relationship would then reuse much of the existing Model system to provide more flexibility to developers. For instance, a Relationship subclass could optionally have fields to describe the relationship, such as "role" in the now-ubiquitous Actor-Film example. In that example, "role" would just be an instance of CharField, just like on a Model. Additionally, by including a separate Relationship class, any defined subclasses could also define a Meta class for more fine-grained control. Using django.db.models.options.Options would be necessary anyway, in order to reuse contribute_to_class() on existing Field types, so it makes sense to just allow developers to define Meta directly if needed. This would allow custom values for db_table (currently impossible for standard M2M), verbose_name and verbose_name_plural (useful for edit_inline, possibly), even ordering and unique_together. Ultimately, the Relationship would create a Model behind the scenes, which will be used to actually store and retrieve the data.This hidden Model would share the Meta options and fields declared on the Relationship, as well as have ForeignKey fields for the related models. This would allow manage.py commands like sql, reset and syncdb to treat it as a standard Django model, rather than having to branch into oddities to handle M2M tables. This would (I hope) replace all of the hackery that's currently in place to deal with the hidden M2M table, swapping it out for something that's far more in line with the rest of Django. For existing code, the ManyToManyField would be modified to simply create a Relationship behind the scenes, and then reference that as if it were supplied by the developer. The base Relationship class would also have a set of methods on it to supply behaviour for add(), remove() and the like. That way, individual Relationships could override those methods to provide custom features, like notification of new relationships, limits on what types of relationships can happen, etc. The questions then become (not meant to be exhaustive): * Should something like this happen? * What fields should a Relationship define? Namely, should the related models be included explicitly as ForeignKeys? * 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? * How would add(), remove() and company reference the related models in a reliable fashion? * How would syncdb generate the SQL for the relationship? * What backward compatibility concerns are there? Personally, I'd answer these questions like so. Yes, it should definitely happen. Obviously, or I wouldn't be recommending it. A Relationship should define all the fields that would be present on a Model that would represent the relationship table. So ForeignKeys would be supplied explicitly on the Relationship class (more on why below). By including ForeignKeys in the Relationship definition, the existing related_name code will kick in and supply a manager on the related Models. Of course, this would have to be modified somewhat to provide a manager more knowledgeable about ManyToMany fields, but that's already being done elsewhere, and should be able to be done here as well (I hope). By being methods on the Relationship itself, add(), remove() and whatnot else would have access to the related models via ForeignKey fields (and other relationship fields via standard mechanisms) directly as attributes of "self". So the signatures for all of them could be simply add(self), remove(self), etc. This way, there's never any confusion, regardless of which direction the relationship is being modified. For the case of adding multiple objects at once, add(self) would simply called multiple times, once for each object being added. Since it would create a true Model behind the scenes, using any options specified in Meta, syncdb would already have everything it needs to generate SQL. Including ForeignKeys ensures that even REFERENCES and the like are generated correctly, without any special handling as an M2M table. For developers using the current ManyToManyField, there would be no change. A Relationship would be created behind the scenes, matching the existing features, like table name and column names. This would then be able to access their existing data without a hiccup. For those using additional fields, who have thus resorted to creating a separate Model for the relationship, they can just change the subclass from models.Model to models.Relationship and the rest comes for free. This is another bonus of specifying ForeignKey fields on the Relationship. I have a little bit of code laid down for this already, but not enough to be nearly functional. If there's sufficient interest in this approach, I'll flesh it out and submit a ticket for it. If not, tell me now so we can discuss other options. -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 -~----------~----~----~----~------~----~------~--~---