Example problem
Say, you have models Publication
, Photo
, Event
and Person
; they could relate to each other in different ways. Particularly, publications can have 1) some illustrations (related photos) and 2) some mentioned personas. Events can have some 3) photos and 4) people related as well. Also, 5) events could be mentioned in publications.
No additional data needs to be associated with relationships, except for illustrations: they need a position field for sorting. So in that case (#1), it's OK to go with intermediate model like Illustration
referencing photo and publication and specifying a position field.
But with cases 2 or 4 it becomes complicated.
It makes sense to specify, say, a ReferencedPerson
which can point to object of any type (via generic foreign key), so it could be used for both publications and events. On the other hand, you can specify ReferencedEvent
, which could be used in cases 5 and 3, but also in the case 4 as well, because you can't really say that it's an event which references a person and not vice-versa.
So at one point it becomes unDRY enough to start thinking about simply specifying a ReferencedObject
model with two generic foreign keys. And this is uncool, this is what tags are for, and if tags could represent another model instances, that would be great.
The idea
Machine tags are tags which could contain namespaces and/or values. They look like namespace:tag=value
(with namespace and value parts optional).
Machine tags can be used not only to hold extra data, but to represent relationships between objects. Rough example would be Flickr, where you can tag a photo with, say, upcoming:event=81334
and it will be automatically displayed as a link to Upcoming.
Possible variants of implementation
There's machinetags
branch of django-tagging
application. It's quite generic and tags there are not considered as referencing objects. I think of writing a app providing helper functions and a template tag or filter which would replace "special" machine tag, say, with referenced object's human readable name.
The question
(Sorry for more than one.) Does it make sense to build relationships between models like that, with machine tags? And if it does, what would be the best way to implement that with Django? What are the cases when it's better to use intermediate models? Am I solving the wrong problem here?
I don't think the use of tagging is appropriate for representing relationships. Of course, it all depends on what kind of queries you want to perform. For regular navigation queries, regular n:m relations should be used. Tagging should be used when the information structure is now known upfront.
来源:https://stackoverflow.com/questions/4477423/machine-tags-referencing-model-instances-in-django