Re: Implementing entity relationships that use compound keys in a Django application

2006-10-04 Thread David S .

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

2006-10-03 Thread Malcolm Tredinnick

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

2006-10-03 Thread Sam Morris
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