Re: Implementing entity relationships that use compound keys in a Django application
Malcolm Tredinnick pointy-stick.com> writes: > > documentation). As you have noted, you also then have to do something > with limit_choices_to and possibly a validator to enforce this at the > Python and form validation level, but it's shouldn't be too bad. Does limit_choices_to work outside of the admin interface? Even within the admin interface, I could not figure out a way to refer, within limit_choices_to, to fields on the record it was to limit for. In other words, I can hard code values in there, but not refer to the value of self.whatever_field. Can limit_choices_to take the name of a function that returns an iterator or something? It would be neat. Also, the validator stuff is in a state of flux, and I have been hesitant to commit much time coding to the current implementation, but that's just me. I ended up adding some Dojo javascript to get the legal values, in this case sub-accounts for a buyer, and populate the html select options when the buyer has been selected. function fill_accounts(evt) { el = document.getElementById("id_buyer"); function results_for_post(type, value, evt) { eval('res='+value); if (res['is_ok']==true) { var account_sel = document.getElementById("id_account"); account_sel.innerHTML = res['html']; } else { alert ("Problem getting info for " + target.value + "."); el.focus(); } } if (el.value != "") { dojo.io.bind({ url: "/admin/manager/participants/"+el.value+"/accounts/?output=json", method: "GET", type: "text/javascript", load: results_for_post, error: function(type, error) { alert("Error getting accounts: " + error); }, }); } return false; } It also makes it so they can not enter an illegal value in this view. Anyway, perhaps the SQLAlchemy branch might someday address this more comprehensively. Peace, David S. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@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-users -~--~~~~--~~--~--~---
Re: Implementing entity relationships that use compound keys in a Django application
On Tue, 2006-10-03 at 17:41 +0100, Sam Morris wrote: > 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. Looks to me like you have thought this through fairly carefully and all of your options are not unreasonable (although I'm not entirely clear on what the first one is). The natural Django way here would be the third option, since Django doesn't handle composite primary keys, but does give you a default surrogate primary key on every table (the implicit "id" attribute, if you don't explicitly set up a primary key). So you already have a surrogate single field to point to in your relations. Your second option would be the DBA way of thinking about this and isn't entirely crazy, either. Django is set up to encourage thinking at the Python model level, rather than the database level, but leaky abstractions are in play here just as everywhere else and you end up being aware of the database anyway. So if you want to install a CHECK() constraint on your database table, you can do it as part of the initial SQL when setting up the models (see the last section in the model API documentation). As you have noted, you also then have to do something with limit_choices_to and possibly a validator to enforce this at the Python and form validation level, but it's shouldn't be too bad. I've been thinking about this problem a little bit on and off lately as part of putting in support for multi-column primary keys (getting the relation API tweaked accordingly is the only really tricky part). I haven't solved it yet, because working out how to express you second option neatly and somehow automatically at the Django model level is not completely obvious to me yet. So all I can say is that I think both your latter two solutions (at leat) would work and the third one is the more natural approach at the moment. Regards, Malcolm > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@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-users -~--~~~~--~~--~--~---
Implementing entity relationships that use compound keys in a Django application
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