No profile page member found matching the query: Profile page of all users (except admin) does not render)

Hello!

I am continuing my Django journey and again turn to this forum for guidance.

Problem definition

Whenever I sign in into the website (I’ve successfully implemented CVB user authentication) with none-admin users, the encounter this error:

What I have done

  • I’ve made sure that the database is not empty; there are plenty of objects to query.
  • I’ve tried to read the Django documentation on CBV and tried to understand all the different methods of the CB-DetailView and query the database.

Project setup:

In my project, I have several apps such as a main app for general functions, authentication app, profilepage app, settings app etc. The issue that I have concerns the profile_app I believe.

My question

  1. How do I render the profile page of a specific user? I not familiar with how dynamic filtering using slug/Pk works when using CBV. I believe that DetailView is the right generic view that I’m using.
  2. What changes do I have to do solve this error described above?

Model 1 - From app: main_app

class Member(PermissionsMixin, AbstractBaseUser):

    # Fields for sign up page
    username = models.CharField(
        _("Användarnamn"), max_length=50, unique=True, default='')
    email = models.EmailField(
        _("Mail"), max_length=100, unique=True, default='')
    age = models.PositiveIntegerField(_("Ålder"), null=True, blank=False)
    country = models.CharField(_("Land"), max_length=50, null=True, blank=True)
    county = models.CharField(_("Län"), max_length=50, null=True, blank=True)
    city = models.CharField(_("Stad"), max_length=50, null=True, blank=True)
    sex = models.CharField(_("Kön"), max_length=50,
                           null=True, blank=True, choices=sex_choices)
    avatar = models.ImageField(
        _("Profilbild"), upload_to="static/user_profile_pics", null=True, blank=True)
    account_created = models.DateTimeField(
        _("Medlem sedan"), null=True, auto_created=True)
    last_login = models.DateTimeField(
        _("Senast inloggad"), null=True, auto_now=True)

    objects = CustomUserManager()
    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []

    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    count = models.IntegerField(null=True, default=0)

    def __str__(self):
        return str(self.email)

Model 2 - From app: profile_app

class ProfilePageMember(models.Model):
    members = models.OneToOneField(Member, on_delete=models.CASCADE)
    education = models.CharField(
        _("Utbildning"), max_length=50, null=True, blank=True, choices=education)
    count = models.IntegerField(null=True, default=0)

    def __str__(self):
        return str(self.members)

Profile_app - View

from typing import Any
from django.conf import settings
from django.db import models
from django.shortcuts import render, redirect
from django.views.generic.detail import DetailView

from profile_app.forms import *
from profile_app.models import *
from messages_app.models import Message

user = settings.AUTH_USER_MODEL
# Create your views here.

# Redirect to user profile from the navbar


class ProfilePageView(DetailView):
    model = ProfilePageMember
    template_name = "profile_app/profilepage.html"
    context_object_name = "current_user"

Profile_app - URL

from django.urls import path
from . import views

app_name = "profilepage_app"

urlpatterns = [
    path("profilsida/<str:pk>/",
         views.ProfilePageView.as_view(), name="profile-redirect"),
]

You can solve this one of two way.

  1. Create the instance of the Profile when the User object is created.
  2. Override the get_object method of your view to create the instance of the Profile if it does not currently exist. (You’d want to verify that the pk being supplied is the pk of a valid user before performing that operation to minimize the chance of your Profile model from being spammed.)

Hello Mr Ken!

  1. Do I use django Signals to do that or are you suggesting anything else?
  2. I did the following changes but it still does not work:
class ProfilePageView(DetailView):
    model = ProfilePageMember
    template_name = "profile_app/profilepage.html"
    context_object_name = "user_data"

    def get_object(self, queryset=None):
        obj = super().get_object(queryset=queryset)
        return obj

I never use Django Signals for anything unless I have no other alternative.
What I would choose to do depends upon how the User object is being created.

You haven’t added any code to detect whether the object exists and to create it if it doesn’t. (And, having done that, you won’t need to call super in your implementation of get_object.)

Couple different points here -

  • Your primary key in ProfilePageMember would be the default id field, which is an integer.
    This url definition then would not be appropriate for retrieving it:

(pk should be an int, not a str)

  • It’s not clear from what you’ve posted whether that parameter is intended to be the pk of the User object or of the Profile object. (The two are not necessarily the same unless you specify primary_key=True in the OneToOneField.)
    When they are different, you need to make sure you understand when you’re passing the pk for the User and when you’re passing the pk of the Profile.

  • Your get_object method could most easily use the get_or_create function to retrieve the instance of the profile.