views:

25

answers:

1

I have several user profile models inherited from one base class like this:

class BaseProfile(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=100)
    ...
    class Meta:
        abstract = True

class DoctorProfile(BaseProfile):
    license_no = models.CharField(max_length=10)
    ...

class PharmacistProfile(BaseProfile):
    pass

When I have a user instance, I would like to get their profile.

I don't feel like checking if the user has a profile one by one with sth. like this:

if user.doctorprofile_set.all().count() == 1:
    return user.doctorprofile_set.all()[0]
elif user.pharmacistprofile_set.all().count() == 1:
    return user.pharmacistprofile_set.all()[0]
...

for each profile is the best way as it is not DRY and requires extra queries on database.

What is the best way to do this?

edit: would be nice to define AUTH_PROFILE_MODULE in settings to point to the base model like AUTH_PROFILE_MODULE = 'profiles.baseprofile' and be able to use user.get_profile() on every user with different profile classes derived from the same base profile.

+1  A: 

Make it a OneToOneField instead of a FK then do user.doctorprofile etc. The OneToOne will throw an Foo.DoesNotExist or Foo.MultipleObjectsReturned, though, if things go wrong, so be prepared to catch those exceptions

stevejalim
thanks, this will make things more neat. but still this approach requires querying each profile possibility one by one which means extra hits to the database and is not very dry, because if a new profile is introduced, another try ... except block should be added to the code that fetches profiles. would be nice to use get_profile() on BaseProfile class. i will update my question.
omat
I didn't say it was perfect. Extending the User model in Django won't get nicer until 1.3/1.4, I gather. And you can always add some code (as I do) which caches the profile the first time it's needed and then invalidates that its key when the model is saved again
stevejalim