Rustam Ganeyev
Rustam Ganeyev

Reputation: 944

Get concrete profile from request.user in Django

I have abstract profile linked to the User:

class Account(models.Model):
   class Meta:
        abstract = True

    user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True)
    patronic_name = models.CharField(max_length=255, default="")
    # additional fields and methods
    def foo(self):
       print('account')

And I have multiple different roles and implementations - student, tutors, admins, etc. I created a class for each of them, derived from the Account class.

class Teacher(Account):
    def foo(self):
        print('teacher')
    # ...additional fields and methods

class Student(Account):
        def foo(self):
            print('student')
    # ...additional fields and methods

Now I want to call foo method on the class object, like this:

@login_required
def index(request):
   request.user.account.foo()

But since Account class is abstract, there is no request.user.account M2M relationship. I have request.user.student, request.user.teacher relationships, but I do not know the type of relationship.

Is there any way to get the concrete account of request.user User object?

Upvotes: 1

Views: 113

Answers (2)

Iain Shelvington
Iain Shelvington

Reputation: 32244

You could add a property to your User model that inspects every subclass of Account and returns the first subclass that has a relationship to the user.

Something like this should work

@property
def account(self):
    for subclass in Account.__subclasses__():
        try:
            return getattr(self, subclass.__name__.lower())
        except DoesNotExist:
            continue

Upvotes: 1

JPG
JPG

Reputation: 88439

Have you tried something like this,

@login_required
def index(request):
    try:
        foo_result = request.user.account.foo()
    except AttributeError:
        foo_result = request.user.teacher.foo()
    ...

Upvotes: 1

Related Questions