I am facing an issue with querying the Profile model based on the user_id of a Project instance in my Django REST framework project. When attempting to retrieve the profile using the user_id, I receive a ValueError with the message "Cannot query 'Shahryar Bin Talib': Must be 'Project' instance."
I have a Profile model with a one-to-one relationship with the built-in User model. The Project model has a foreign key relationship with the User model, and I want to retrieve the Profile instance related to the specific Project using the user_id. I have checked the profile instance after the query and the profile is retrieved successfully.
Views.py
queryset = Project.objects.all()
serializer_class = ProjectSerializer
@action(methods=['get', 'put', 'post'], detail=True, url_name='project_profile', url_path='profile')
def project_profile(self, request, pk):
try:
project = Project.objects.get(id=pk)
except Project.DoesNotExist:
return Response({'error': 'Project does not exist.'}, status=status.HTTP_404_NOT_FOUND)
profile = project.user.profile
serializer = ProfileSerializer(profile)
return Response(serializer.data)
serializers.py
user = serializers.ReadOnlyField(source='user.username')
skills = serializers.StringRelatedField(many=True)
project = ProjectSerializer(source='user.project', many=True)
class Meta:
model = Profile
exclude = ['bio']
models.py
class Project(TimeStampedModel):
""" A model representing a project """
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
blank=True,
related_name='project',
help_text='The user that created the project.'
)
title = models.CharField(
max_length=200,
blank=True,
null=True,
help_text='The title of the project.'
)
description = models.TextField(
blank=True,
null=True,
help_text='The detailed description of the project.'
)
class Profile(TimeStampedModel):
""" Model representing a user profile """
user = models.OneToOneField(
User,
on_delete=models.CASCADE,
blank=True,
null=True,
help_text='The related user.'
)
skills = SortedManyToManyField(
'Skill',
blank=True,
related_name='profile',
help_text='The skills associated with the profile.'
)
short_intro = models.CharField(
max_length=100,
blank=True,
null=True,
help_text='A short intro or a post title.'
)
Here is the pdb: `/Users/uzair.imtiaz/Desktop/Code-Book/api/views.py(41)project_profile() -> try: (Pdb) n
/Users/uzair.imtiaz/Desktop/Code-Book/api/views.py(42)project_profile() -> project = Project.objects.get(id=pk) (Pdb) n /Users/uzair.imtiaz/Desktop/Code-Book/api/views.py(46)project_profile() -> profile = project.user.profile (Pdb) n /Users/uzair.imtiaz/Desktop/Code-Book/api/views.py(47)project_profile() -> serializer = ProfileSerializer(profile) (Pdb) p profile.date_of_birth datetime.date(2002, 8, 14)`
It is not any different than this:
class ProfileViewSet(viewsets.ModelViewSet):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
@action(methods=['get', 'put', 'post'], detail=True, url_name='profile_projects', url_path='projects')
def profile_projects(self, request, pk):
try:
projects = Project.objects.filter(user_id=pk)
except Project.DoesNotExist:
return Response({'error': 'Profile does not exist.'}, status=status.HTTP_404_NOT_FOUND)
serializer = ProjectSerializer(projects, many=True)
return Response(serializer.data)
if this is working why is it raising that error on project_profile
Issue
You're trying to access it like this
Project > User > Profile
While your database relations are like this, Project > User Profile > User
User model doesn't have profile attribute, its the Profile mode which has the user attribute.
Fix
You can define a
related_namewith user field in Profile Model to access profile from user objectYou can then access it like,