On 5/31/07, Russell Keith-Magee <[EMAIL PROTECTED]> wrote: > However, you're not the first to propose this. In fact, I would doubt > that you are even the tenth. This is a pretty common request.
Yeah, I know I had seen at least one mention of it before, and I figured it was fairly common. I was just havnig trouble tracking down any prior discussions on the topic, so I had little to go on. > Your suggestion seems to be more on the lines of pseudo-adding the > entire relation _model_ to the related classes: > > Actor.objects.filter(films__title='Fight Club') > Actor.objects.filter(roles__role='Tyler Durden') Admittedly, I hadn't gone far enough into it to consider how filters like that would operate, so I'm actually fairly open to using whatever method works best. Right now, the manager actually returns a QuerySet based entirely on the destination model, using .extra(select=...) to add in the fields from the join model. It's really quite primitive at this point, since my first concern was accessing the data from templates. Comments like yours are precisely why I wanted to bring it to the list. :) > This are still some namespace clash problems, but they're much smaller > than previous suggestions, and the semantic ambiguity (i.e., the > implication of attributes on the related model that aren't actually > there) isn't as pronounced. As for the namespace clash problems, I figured the manager, during its contribute_to_class, could check the fields on each related model, and if there are any duplicates, throw and error. That way, something like that would fail even during 'manage.py validate'. As for semantic ambiguity, I had given a little bit of thought to it, and there's only so much that can be done to help that situation. The one thing I'd insist on is that the result model (such as the Actor taken from film.actors.filter(name='John Cleese')) would never update the relationship when its .save() is called. That, of course, is current functionality anyway, and I would think that changing it would cause far too many headaches. That's why the wiki article recommends the addition on an .update() method on the manager. > To add to your proposal, I would say that the pseudo-attribute should > derive its name from the relation name: > > Actor.objects.filter(film_roles__role='Tyler Durden') > Film.objects.filter(actor_roles__role='Tyler Durden') > > Specifically, this is avoid problems when you have two m2m relations > with a relation model (not a problem for this scenario, but certainly > conceivable). It also has the advantage of reducing the semantic > ambiguity a little further. Again, I hadn't done any work yet on how filters would work, so this seems like a reasonable approach. The manager already returns a custom subclass of QuerySet to add in the relationship data, so adding in extra filter behavior should be straightforward. > Regarding syntax; Jacob's suggestion is the usual suggested syntax for > proposals in this direction, and I'd have to say I prefer that syntax > to your M2MManager idea. To boot, Jacob's syntax should actually fit > into the existing contribute_to_model framework without too much > difficulty. I admit I hadn't considered any alternative syntax, but that's mostly because I couldn't find any previous discussion. I'm definitely open to alternatives, but I'll at least explain why I chose the syntax I proposed: it falls very much in line with the existing recommendation for defining joiner models. The main advantage to the manager concept is that projects could maintain all their existing models and databases, without having to destroy anything. All they'd have to do is add the manager to whichever models they were already using, optionally change the related_names to make more sense, and update their other code to use the new API. No manual schema changes would be necessary. There is (at least) one substantial pitfall to my syntax, however. It's fairly easy to implement basic retrieval (already done) and the .update() method (again, already done), and the filter modifications should be simple enough, but extending the .add() method is currently impossible without a patch to django.db.models.fields.related. The RelatedDescriptor subclasses the model's default manager and adds its own .add(), so anything I put on my manager gets completely ignored. And I'm not about to add a separate method, since that would not only be inconsistent with other relationship types, but it would also still leave the existing .add() in place, even though it wouldn't function as expected. I'm not sure how much of a patch to the RelatedDescriptor process would need to happen to get .add() working, but it's certainly enough of a trouble to investigate alternatives. So, there's a bit more to chew on; hopefully we can come up with some final thoughts on this soon, because I'd love to see this happen. -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 -~----------~----~----~----~------~----~------~--~---