Profile matching query does not exist.

I am trying to access a user’s profile, the user is logged in via admin but I get this error when trying to access the portal " DoesNotExist at /profile/2" - “Profile matching query does not exist.”.

How can I correct this please?

MODELS.PY

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(blank=True)
    follows = models.ManyToManyField("self", related_name="followed_by", symmetrical=False, blank=True)

    def __str__(self):
        return self.user

URLS.PY

    path("profile/<int:user_id>", views.profile, name="profile"),

PROFILE.HTML

{% extends "network/layout.html" %}

{% block body %}
<div class="col-5 profile__wrapper">
    <div class="header__wrapper">
      <!-- <div class="header_headerimg">
        <img src="http://placeimg.com/640/480/nature" alt="User background image" />
      </div> -->
      <div class="cols__container cols-container">
        <div class="content__col">
          <div class="img-container">
            <img src="http://placeimg.com/140/140/people" alt="User image" />
            <span></span>
          </div>
        <form method="POST">
            {% csrf_token %}
            <h2>{{ profile_user }}</h2>
            <p>@{{ profile_user }}</p>
            <input type="hidden" value="{{user.username}}" name="follower">
            <input type="hidden" value="{{user_object.username}}" name="user">

            <strong>Follows</strong> <br/>
            
            {% for following in profile.follows.all %}
                @ {{ following }} <br/>
            {% endfor %}

            <strong>Followed by</strong> <br/>
            {% for following in profile.followed_by.all %}
                @ {{ following }} <br/>
            {% endfor %}

        </form>
</div>
      </div>
    </div>
</div>
{% endblock %}

VIEWS.PY

def profile(request, user_id):
    if request.user.is_authenticated:
        profile = Profile.objects.get(pk = user_id)
        context = {
            "profile": profile,
        }
        return render(request, "network/profile.html", context)
    else:
        context = {
        "profile": profile,
    }
        return render(request, "network/profile.html", context)

The error I see is coming from Views - profile = Profile.objects.get(pk = user_id)

When I edit this to the below code, it shows but my profile name on Profile.html is blank i.e ’ {{ profile_user }}’

        profile = User.objects.get(pk = user_id)

The issue here is that the user field in Profile is not necessarily the same value as the id field in that instance.

This means that:

and

might be referring to two different objects.

If user_id is the pk of the User object, then you need to compare the foreign key in Profile to User.

In this case then it may look like:
Profile.objects.get(user_id=user_id)

This returns the same error

The error is specifically saying that you don’t have an instance of Profile that refers to that user.

What data do you have in the Profile model? (How many entries are in that table?) What user_ids are present?)

I checked, I had no profile data showing in my admin panel until I added one, is there a way for me to inherit data directly from the User Model when a user is created i.e I would like if when a user is created, it automatically creates a profile for that same user and stores the data in the Profile Model.

This may be my best option if the above is not available as I would not like for a user to need to create profiles manually after their user account is created for this particular project.

What do you think?

Yes, that’s an appropriate approach.

How are you creating users? Through the admin, or do you have other views to do this?

Through admin, I don’t have a separate view for this

In that case, you might want to use the get_or_create function for Profile instead of get. That will create the object the first time you try to reference it. It’s going to be easier to do it that way instead of adding something to the admin class.

1 Like

Let’s see what’s going on.


1. Why are you having this error?

Here is the thing:

Sometimes it could happen that the user id and the profile id differ.

So when you do:

profile = Profile.objects.get(pk = user_id)

You’re assuming that the profile id is the same as the user’s id. Which it could not be the case. Suppose you first created two users and later on you added the profile to your app. You already have two users (id 1 and 2). When you create a new user with id 3, this will have a profile with id 1, because it’s the first profile record.

An example will help:

A) The auth_user table:

id username
1 user_1
2 user_2
3 user_3
4 user_4

B) The <app_name>_profile table, where user_id shows the relationship with User.

id user_id
1 user_3
2 user_4

Profile with id 1 has a relationship with user_3.
Profile with id 2 has a relationship with user_4.

But user_1 and user_2 do not have a profile.


This is the model:

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

If you want to get the user’s profile in a view, you should do something like this:

#views.py
def update_user(request, user_id_request):
    if request.user.is_authenticated:
        current_user = User.objects.get(id=user_id_request)
        current_profile = Profile.objects.get(user_id=user_id_request)

This is the critical part:

current_profile = Profile.objects.get(user_id=user_id_request)

I changed the parameter’s name in the view just to show a different name so you can see that user_id refers to a column in the table <app_name>_profile and user_id_request is part of the request.

Your error DoesNotExist at /profile/2 shows that there is not a profile for the referenced user_id_request = 2.

To me, when this kind of problems arise, I like to see the database directly and not the admin alone (Like the tables I showed above).


1. How to create a profile automatically after creating a user?


There are different ways.
Here I comment one.

You can use Django’s signals to automatically create a Profile instance when a new User instance is created. Specifically, you can use the post_save signal. Here’s an example of how you can achieve this:


#models.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save

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

    def __str__(self):
        return self.user.username

def create_profile(sender, instance, created, **kwargs):
    if created:
        user_profile = Profile(user=instance)
        user_profile.save()

post_save.connect(create_profile, sender=User)

I hope this helped!! :muscle:

@guzmanojero - I appreciate you taking the time and effort to craft this post. However, this thread is more than 9 months old, and the person who posted it hasn’t logged on here since last July.
You may want to take these factors into consideration when choosing a topic to respond to.

Side note: I recommend against using signals for this. There are a number of situations in which a signal does not get triggered, which means you still won’t have a profile model created.

That is why I recommend using the get_or_create function whenever the profile is needed. If the profile model exists, everything is ok. But if the profile model hasn’t yet been created, one will be.

1 Like

Thanks!

I just answer for the OP, but also for my future self and for others as well :wink:

“Side note: I recommend against using signals for this. There are a number of situations in which a signal does not get triggered”


Thanks for the recommendation 💪