Hello everyone! I am new to Django and am currently learning how to use the model API. I am trying to construct a set of models to represent a number of people (characters in a game), who can be members of one or more organisations. Each person in an organisation has a rank in that organisation. My original sketch of how I would do this directly in a database looks like this:
Person
Organisation
Rank (*organisation, *rank, name)
Membership (*person, *organisation, rank)
Membership.person -> Person
Membership.(organisation + rank) -> Rank
Asterisks denote primary keys; where more than one field has an asterisk
then the primary key is a compound key.
My problem is that Membership.(organisation + rank) is a compound
foreign key, which Django does not support. My current implementation of
the relationship uses a linkage model:
class OrgMembership (models.Model):
person = models.ForeignKey (person)
organisation = models.ForeignKey (Organisation)
rank = models.ForeignKey (Rank)
class Meta:
unique_together = [['person', 'organisation']]
This allows OrgMembership.rank to be set to any possible rank, but I
only want to allow OrgMemberships where Rank.organisation ==
OrgMembership.organisation.
The solutions I have come up with so far are:
* Forget the relationship between Membership.rank and Rank -- turn
OrgMembership.rank into a simple integer
* Create a database constraint to enforce the restriction, and
somehow alter the admin page to only allow legal values (using
limit_choices_to?)
* Give the OrgMembership model a custom validation rule
(presumably complemented by a manually-created database
constraint)
* Decompose the relationship somehow
By 'decompose' I mean changing the schema to something like this:
Rank (level, name)
OrgRank (organisation, rank)
OrgMembership (person, org_rank)
The final option is probably the best one, but I thought I would post
anyway to see if any more experienced users could confirm/deny, and to
see if there are any other approaches that I have missed.
--
Sam Morris
http://robots.org.uk/
PGP key id 1024D/5EA01078
3412 EA18 1277 354B 991B C869 B219 7FDB 5EA0 1078
signature.asc
Description: This is a digitally signed message part

