Reputation: 1071
I have several models representing different type of user profiles,
class User(models.Model):
pass
class ProfileA(models.Model):
user = models.OneToOneField(User, related_name="%(app_label)s_%(class)s_related",)
class ProfileB(models.Model):
user = models.OneToOneField(User, related_name="%(app_label)s_%(class)s_related",)
class ProfileC(models.Model):
user = models.OneToOneField(User, related_name="%(app_label)s_%(class)s_related",)
Now, let's say I get the user instance: how can I get the related profile object? All three profile models(in my code I've 6 different profile models extending BaseProfile model, which is abstract) have additional fields, and I basically need the whole profile object accessible from within User object instance.
Upvotes: 2
Views: 1126
Reputation: 16032
The docs recommend using hasattr
, but in your case that can get a bit messy.
To simplify the process, I would subclass the base User
model, then create a custom method to fetch it's own profile.
for example:
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
def get_profile(self):
if hasattr(self, 'profile_a'):
return self.profile_a
elif hasattr(self, 'profile_b'):
return self.profile_b
elif hasattr(self, 'profile_c'):
return self.profile_c
class ProfileA(models.Model):
user = models.OneToOneField(User, related_name='profile_a', on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=45)
class ProfileB(models.Model):
user = models.OneToOneField(User, related_name='profile_b', on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=45)
class ProfileC(models.Model):
user = models.OneToOneField(User, related_name='profile_c', on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=45)
Now you can get the profile of any User
object:
def view(request):
user = request.user
print(user.get_profile())
Also, don't forget to tell django that you created a new user model, by adding AUTH_USER_MODEL = 'yourapp.User'
to your settings.py.
Upvotes: 1
Reputation: 1295
the app name is the name of the app in installed apps with dot references replaced with underscores, for instance for the app myapp
user = User.objects.get(...)
a = user.myapp_profilea_related
b = user.myapp_profileb_related
c = user.myapp_profilec_related
you can get these values programatically via the _meta
property which is an instance of your Meta subclass:
user = User.objects.get(...)
a = getattr(user, f'{ProfileA._meta.app_label}_{ProfileA._meta.model_name}_related')
b = getattr(user, f'{ProfileB._meta.app_label}_{ProfileB._meta.model_name}_related')
c = getattr(user, f'{ProfileC._meta.app_label}_{ProfileC._meta.model_name}_related')
Upvotes: 1