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

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to