0
votes

I am attempting to create a website where all user profiles are public. I have used AbstractUser for any changes to the base user model later on. I made the remainder of the user information in a UserProfile model.

As of now, regardless of the profile I click on I am only seeing information for the currently logged-in user.

This is my first time using class-based views and I think I'm veering off into the wrong direction.

# users/models.py
import uuid # for profile slugs
from django.db import models
from django.conf import settings
from django.db.models.signals import post_save # signal for profile creation
from django.contrib.auth.models import AbstractUser # import base user model for profile
from django.dispatch import receiver 
from allauth.account.signals import user_signed_up

class CustomUser(AbstractUser):
    pass


class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    city = models.CharField(max_length=60, default="")
    ...
    profile_uuid = models.UUIDField(
      primary_key=False,
      default=uuid.uuid4,
      editable=False,
      unique=True
    ) # to use as a "slug" for profiles

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

    @receiver(post_save, sender=CustomUser)
    def create_user_profile(sender, instance, created, **kwargs):
       if created:
          UserProfile.objects.create(user=instance)

I'm trying to use the profile_uuid as my "slug" for the URL. It will come up as "https://example.com/profile/".

# urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')), # allauth user management
    path('profile/', include('users.urls')), # user profiles
    path('', include('pages.urls')), # static pages 
]

# users/urls.py
from django.urls import path

from .views import UserProfilePageView

app_name = 'users'

urlpatterns = [
    path('<profile_uuid>', UserProfilePageView.as_view(), name='user_profile'), # profile page views
]

The view function is using the profile_uuid as my slug, with it referenced in the template as well.

# users/views.py

from django.views import generic
from .models import UserProfile

class UserProfilePageView(generic.DetailView):
    model = UserProfile
    template_name = 'account/profile.html'
    slug_field = 'profile_uuid'
    slug_url_kwarg = 'profile_uuid'

I'd received a few errors for a missing pk or slug field while creating this, eventually I decided to use a UUID as the slug field. The link on the home page (a loop listing all users) uses the profile_uuid as the URL passed to the users/urls.py file. I'm attempting to show the info, with no luck.

# templates/account/home.html

...
{% for p in profile %}
<a href="{% url 'users:user_profile' p.profile_uuid %}">Profile</a>
{% endfor %}
...

# templates/account/profile.html

{% extends '_base.html' %}
{% load crispy_forms_tags %}

{% block content %}
    <h1>{{ user_profile.profile_uuid }}</h1>
    <p>{{ user_profile.email }}</p>
{% endblock content %}

The above are two attempts at pulling the profile information. Obviously the email would be stored in the CustomUser model; however, I was attempting to determine how I'd pull it through the OneToOneField that I have in the UserProfile.

Additionally, the profile_uuid should show up (it's in the URL), but it doesn't print to the page. I've attempted all manner of variations to user_profile, userprofile, etc. with no luck.

Any direction on the matter would be much appreciated. The end result will (hopefully) be a profile handler that will show profiles of others, then on click for the personal profile it will have edit features available.

Cheers!

1

1 Answers

0
votes

The DetailView will expose the model instance in the template as object as per the documentation.

Change your template to:

<h1>{{ object.profile_uuid }}</h1>
<p>{{ object.user.email }}</p>