Pablo
Pablo

Reputation: 69

Extending Django User with subclasses

Due to my app requeriments I need an hierachy of users classes like:

class CommonUser(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    photo = models.ImageField(upload_to="profileImages",blank=True,null=True)  
    #HERE: Common properties for every user
    class Meta:
        abstract = True

class Installer(CommonUser):
    #HERE: Specific properties for Installer Companies


class Administration(CommonUser):
    #HERE: Specific properties for Administration


class Client(CommonUser):
    #HERE: Specific properties for Clients

Well, in view.py I need to get the profile image for an user. I get the user by the request, so I have an models.User objects and I dont know to witch class it belong. Im not able to do:

request.user.commonuser.photo

because user object doesnt have any OnetoOne relation with commonuser but with installer/administration/client...

Any idea? Thanks!

Upvotes: 0

Views: 332

Answers (2)

PANDA Stack
PANDA Stack

Reputation: 1363

I'm on mobile, so I can't test this, but...

I would set a "related_name" on your CommonUser.user field called "commonuser". Then you can just use:

request.user.commonuser.photo

like you are already.

I think the issue is that you are referencing a Django User object to reference a backwards relationship without the proper name.

Upvotes: 1

First off, I think this model is more of a Profile than User. If you don't mind using 1.9 (and postgres) then this is a perfect usecase for a JSON field. You can filter with regular lookups and don't need to specify each type. That way you can also extend the user model in such a way that a user can fulfill many roles at once. The other thing I thought of was linking it the other way around:

class UserProfile(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    # ...

class Installer(models.Model):
    profile = models.ForeignKey(UserProfile, related_name='installer')
    #HERE: Specific properties for Installer Companies


class Administration(models.Model):
    profile = models.ForeignKey(UserProfile, related_name='admin')
    #HERE: Specific properties for Administration


class Client(models.Model):
    profile = models.ForeignKey(UserProfile, related_name='client')
    #HERE: Specific properties for Clients

Upvotes: 0

Related Questions