Adding properties to models at run-time.

3 views
Skip to first unread message

Alex G

unread,
Oct 30, 2008, 4:11:36 PM10/30/08
to Django users
Hi,

I've been trying for some time to create a polymorphic link with a
backwards-link from the associated model. The problem is the model is
django.contrib.auth.models.User... Is there any way to add this
functionality without changing the django core? Trying to call
setattr(django.contrib.auth.models.User, 'target',
generic.GenericRelation(MyUser) does not work. It instantiates an
attribute named 'target', but it doesn't work in the manner
intended...

from django.contrib.auth.models import User as Account
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class User(models.Model):
account_polymorphic_link = models.ForeignKey(ContentType)
account_id = models.PositiveIntegerField()
account = generic.GenericForeignKey('account_polymorphic_link',
'account_id')

setattr(Account, 'target', generic.GenericRelation(User)) #this
doesn't seem to work

My problem is that I'm using auth.User (Account in the above example)
to store username/password and to leverage permissions and such, but I
can't look someone up by username and get at the information in my
derivative class...

Does anyone have any ideas/suggestions?

Thank you,

Alex.

Daniel Roseman

unread,
Oct 30, 2008, 4:33:07 PM10/30/08
to Django users
Well, you can use generic relations without the backwards link, by
simply looking up the content_type/object_id in the related class.

But for your use case, a much better way is to use the built-in
AUTH_PROFILE_MODULE setting, which allows you to nominate a class
which extends User, and enables a user.get_profile() method. See
http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

--
DR.

Alex G

unread,
Oct 30, 2008, 6:13:12 PM10/30/08
to Django users
Thanks for the reply, DR.

How would I use the generic relationship without the backward link?

I have the normal auth.user class, and I have the my.user class that
extends it and has a polymorphic link pointing at auth.user. The
problem occurs when I collect a login/password, because I can't lookup
my.user without the backward link, that is I can't
my.user.filter(account__username = x, account__password = y) because
polymorphic links don't allow this. I also can't move in reverse, the
auth.user.authenticate(username, password) function returns an
auth.user, and I am unclear as to how I would get a my.user from this
information without calling for my.user.objects.all() and comparing
the link (which seems terribly, terribly inefficient...). Is there a
way to start with the target (auth.user) and get to my.user backward
via the contenttype?

I know about AUTH_PROFILE_MODULE, but the problem is that the goal is
to have multiple user classes. Ideally there would be a way to
specify the user model as an attribute of the auth.user model (which
would be the heretofore missing backward link), but barring that this
isn't much use to me because the AUTH_PROFILE_MODULE would have
multiple values.

Any clues?

Thanks,

Alex.



On Oct 30, 4:33 pm, Daniel Roseman <roseman.dan...@googlemail.com>
wrote:
> which extends User, and enables a user.get_profile() method. Seehttp://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-...
>
> --
> DR.

Daniel Roseman

unread,
Oct 31, 2008, 5:38:37 AM10/31/08
to Django users
On Oct 30, 10:13 pm, Alex G <alexander.gir...@gmail.com> wrote:
> Thanks for the reply, DR.
>
> How would I use the generic relationship without the backward link?
>
> I have the normal auth.user class, and I have the my.user class that
> extends it and has a polymorphic link pointing at auth.user.  The
> problem occurs when I collect a login/password, because I can't lookup
> my.user without the backward link, that is I can't
> my.user.filter(account__username = x, account__password = y) because
> polymorphic links don't allow this.  I also can't move in reverse, the
> auth.user.authenticate(username, password) function returns an
> auth.user, and I am unclear as to how I would get a my.user from this
> information without calling for my.user.objects.all() and comparing
> the link (which seems terribly, terribly inefficient...).  Is there a
> way to start with the target (auth.user) and get to my.user backward
> via the contenttype?

Something like (where 'dj_user' is the instance of
contrib.auth.models.User):

User.objects.get(account_id=dj_user.id,
account_polymorphic_link=ContentType.objects.get_for_model(dj_user))
--
DR.
Reply all
Reply to author
Forward
0 new messages