Juan Martin Zabala
Juan Martin Zabala

Reputation: 801

How to link to user's profile on django

I have been trying to link to user's profile page but everytime I try it, it returns a 404 error. I dont know but maybe the error is on the urls.py file.

views.py

    def profile(request, username=None):
      if username:
        post_owner = get_object_or_404(User, username=username)

      else:
        post_owner = request.user

      args1 = {
        'post_owner': post_owner,
      }
      return render(request, 'profile.html', args1)

urls.py

    urlpatterns = [
      path('<str:username>/', views.profile, name='profile'),
      path('login', views.login, name='login'),
      path('register', views.register, name='register'),
      path('logout', views.logout, name='logout'),

    ]

index.html

    <a class="nav-link" href="{{ request.user }}">{{ user.username }}</a>

Upvotes: 2

Views: 2125

Answers (2)

Smit Patel
Smit Patel

Reputation: 63

"@Willem Van Onsem" has given perfectly correct answer. But one thing I want to add is to prevent the overlap. You can rearrange the rules and put that rule at bottom of all rules. because django checks the rule from top to bottom and stop matching when first match is found.

urlpatterns = [
        path('login/', views.login, name='login'),
        path('register/', views.register, name='register'),
        path('logout/', views.logout, name='logout'),

        path('<str:username>/', views.profile, name='profile'),
 ]

things should work fine. But, as commented, we have to put validation that user can't use username from any above path name, like login, register or logout. Also, would like to suggest that don't use these kind of patterns, instead use at least small prefixes like u/<profile> or u/<id> etc, which can be seen in many existing applications like gmail.

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476493

You should link it with:

<a class="nav-link" href="{{ request.user.username }}">{{ user.username }}</a>

but better would be to use an {% url … } template tag [Django-doc]:

<a class="nav-link" href="{% url 'profile' username=request.user.username %}">{{ user.username }}</a>

Your paths also overlap, this means that you will never be able to access login, register or logout, since the first path will "fire" with the idea that username='login'.

You better define non-overlapping paths, like:

urlpatterns = [
    path('profile/<str:username>/', views.profile, name='profile'),
    path('login/', views.login, name='login'),
    path('register/', views.register, name='register'),
    path('logout/', views.logout, name='logout'),
]

Upvotes: 1

Related Questions