Reputation: 2649
I have a Profile model like this:
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile')
about = models.TextField()
When I try to access UserProfile
data from User
instance I get this error:
In [1]:
In [1]: from django.contrib.auth.models import User
In [5]: u = User.objects.all()[0]
In [6]: u
Out[6]: <User: admin>
In [13]: u.profile
---------------------------------------------------------------------------
RelatedObjectDoesNotExist Traceback (most recent call last)
<ipython-input-13-679bed70444a> in <module>()
----> 1 u.profile
~/project/djangoedu/env/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py in __get__(self, instance, cls)
402 "%s has no %s." % (
403 instance.__class__.__name__,
--> 404 self.related.get_accessor_name()
405 )
406 )
RelatedObjectDoesNotExist: User has no profile.
In [14]: u.author
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-14-327f8c8449fd> in <module>()
----> 1 u.author
AttributeError: 'User' object has no attribute 'author'
In [15]:
Upvotes: 0
Views: 338
Reputation: 25
In Django models, when you create a relationship between two models using fields like ForeignKey or OneToOneField, Django automatically generates a reverse relationship to allow you to access related objects from the other side of the relationship. By default, Django generates a related name based on the name of the related model in lowercase.
However, you can customize this related name using the "related_name" attribute. In code below, I have set "related_name" to "profile" in the OneToOneField between the UserProfile and User models. This means that you can access the UserProfile instance associated with a User instance using the "profile" attribute.
For example, when you have a User instance called user, you can access their related UserProfile instance like this:
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
phone = models.CharField(max_length=21, default='', null=True, blank=True)
postcode = models.CharField(max_length=11, default='', null=True, blank=True)
# First, get the user by their ID
user = User.objects.get(id=1)
# Access and print the user's phone number from their profile
print(user.profile.phone)
# Access and print the user's postcode from their profile
print(user.profile.postcode)
Attached is a real example using a Python shell to elucidate the scenario.
Upvotes: 0
Reputation: 47354
From the docs:
A DoesNotExist exception is raised when accessing the reverse relationship if an entry in the related table doesn’t exist.
So before accessing user's profile, you need to create this profile first:
u = User.objects.all()[0]
UserProfile.objects.create(user=u)
Upvotes: 1
Reputation: 522
Try it like this
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User, related_name="profile")
Upvotes: 0