views:

38

answers:

2

I have an abstract base class for defining common attributes shared by different user profiles.

class Profile(models.Model):
   ...

   def has_permissions(self, project):
      ...

   class Meta:
      abstract = True

class Standard(Profile):
   ...

class Premium(Profile):
   ...

Now I would like to check the permission of a certain user (having always one distinct profile assigned) without having to know which profile he has, like

user.profile.has_permission(project)

But this does not work because the "Profile" base class is abstract. Is there a way to circumvent this problem? And is there a way to discover the name of the abstract parent class from a child object?

Thanks, Daniel

A: 

I am not entirely convinced that this is the best approach to take. The code is correct in the object sense of things but does not seem to fit the database view (IMHO). User will only have one profile but the database table will have links to multiple Profile tables.

How about:

  1. Make profile at generic relation which can connect to any kind of Profile
  2. Have a single Profile class and define permissions based on instance attribute ('premium' or 'standard')

I am curious to know what others think.

Manoj Govindan
What kind of advantage do you see in your approach compared to a non-abstract Profile base class? This would have been my prefered approach. But as the system is already in a productive state I can not make the Profile class non-abstract.The reason I don't like this approach is because I would like to be able to add profiles without changing every part in the code where I am checking permissions.
Daniel
@Daniel: this guy has said it much better :) http://www.pbell.com/index.cfm/2006/10/14/ORM-Approaches-to-Inheritance
Manoj Govindan
A: 

overwrite the auth.User method get_profile() to investigate in all Child-Profile Models Until you find it:

  class MyUser(auth.models.User):
        profile = models.OneToOneField(Profile)
        def get_profile(self):
            prof = None
            try:
                prof = Standard.objects.get(id=self.profile.pk)
            except ObjectDoesNotExist:
                prof = Premium.objects.get(id=self.profile.pk)
            return prof

now, Instead of doing this:

user.profile.has_permission(project)

you can use this:

user.get_profile().has_permission(project)

i hope that it will help you.

Dantario
Dantario: Sometimes seemingly complicated things can be so easy. Especially because I already implemented the get_profile method like this :-). Seems like I missed the wood for the trees. Thanks for your help!
Daniel