[Django]-Generic detail view UserProfileDetailView must be called with either an object pk or a slug in the URLconf

4👍

Problem

  1. str type used instead of slug type in urls.py
  2. UserProfileDetailView doesn’t specify your custom slug_url_kwarg and slug_field
  3. UserProfileDetailView specifies UserProfile model but UserProfile model doesn’t have attribute or method username, which is on `User table.

Solution

Reading Django’s DetailView code, you’ll find that the following is necessary to get your code working properly.

Update class attributes

views.py

class UserProfileDetailView(DetailView):
    slug_url_kwarg = "username"
    slug_field = "username"

Update UserProfile model OR Update UserProfileDetailView.get_slug_field

UserProfile is the lookup table defined for UserProfileDetailView and get_slug_fieldmethod, which readsslug_fieldproperty on the UserProfileDetailView doesn't support dot syntax method traversal (ie:user.username`).
Thus either:

  1. UserProfile model must have reference to username or;
  2. get_slug_field must explicitly define slug field or;
  3. get_slug_field must add functionality for dot syntax method traversal

models.py

class UserProfile(models.model):
    ...
    
    @property
    def username(self):
        self.user.username 

OR

class UserProfileDetailView(DetailView):
    ...

    def get_slug_field(self):
        self.user.username

Update username type in urls.py

Helpful, but not necessary.

urls.py

path('<slug:username>/', UserProfileDetailView.as_view(), name = 'detail'),

References

Django Detail View get_slug_field (Github): https://github.com/django/django/blob/master/django/views/generic/detail.py#L78-L80

👤pygeek

0👍

you need to add the user pk or slug in the url so that django can retrieve the user using this pk or slug
so edit the url to be like this

path('<slug:username>/',UserProfileDetailView.as_view(),name = 'detail'),

but make sure that your slug equal the username of the user , to do this override the save method in your model to be like this

def save(self, *args, **kwargs): 
    self.slug = self.username
    super(Your_Model_Name, self).save(*args, **kwargs)  

make sure to change ‘Your_Model_Name’ with your model class name

0👍

Set slug_url_kwarg–(Django Doc) and slug_field–(Django Doc) attributes on your view class


class UserProfileDetailView(DetailView):
    slug_url_kwarg = "username" # this the `argument` in the URL conf
    slug_field = "your_model_field" # this is the model field name.

    # Rest of your code
👤JPG

Leave a comment