django username in url, instead of id

后端 未结 5 711

in a mini virtual community, i have a profile_view function, so that i can view the profile of any registered user. The profile view function has as a parameter the id of th

相关标签:
5条回答
  • 2020-12-30 18:32

    Here's how I do it using class based generic views and the use of slugs. It's surprisingly easy and requires only a few lines of code with the help of slugs.

    # accounts/views.py
    from django.contrib.auth.models import User
    from django.views.generic.detail import DetailView
    
    class UserProfileView(DetailView):
        model = User
        slug_field = "username"
        template_name = "userprofile.html"
    
    # accounts/urls.py
    from views import UserProfileView
    urlpatterns = patterns('',
        # By user ID
        url(r'^profile/id/(?P<pk>\d+)/$', UserProfileView.as_view()),
        # By username
        url(r'^profile/username/(?P<slug>[\w.@+-]+)/$', UserProfileView.as_view()),
    )
    

    Now you can access both the user like accounts/profile/id/123/ as well as accounts/profile/username/gertvdijk/.

    What's happening here?

    • The usually required pk URL parameter is omitted and replaced by slug in the URL pattern. This is accepted by the view, because...
    • The slug parameter is being used by the DetailView (or any other SingleObjectMixin-based view) to find the object on User.username by the use of model = User and slug_field = "username". (docs)
    • Because a slug field is optional, the view is also happily serving using just the pk parameter.
    0 讨论(0)
  • 2020-12-30 18:32

    For Django 2.0 and above:

    path(‘profile/<username>/, views.profile, name=‘profile’),
    
    0 讨论(0)
  • 2020-12-30 18:38

    In urls.py

    urlpatterns = [
        path('<str:username>/', UserDetailView.as_view(), name='user_detail'),
    ]
    

    With class based view.

    class UserDetailView(LoginRequiredMixin, DetailView):
    
        model = User
        slug_field = "username"
        slug_url_kwarg = "username"
        template_name = "account/user_detail.html"
    
        def get_object(self):
    
            object = get_object_or_404(User, username=self.kwargs.get("username"))
    
            # only owner can view his page
            if self.request.user.username == object.username:
                return object
            else:
                # redirect to 404 page
                print("you are not the owner!!")
    

    I have tested in Django 2.1.

    0 讨论(0)
  • 2020-12-30 18:39

    You don't show what you have tried, or where you are having trouble. This is fairly simple, after all - just pass a username string to the function instead of an integer, and look up based on that.

    def profile_view(request, username):
        u = User.objects.get(username=username)
    

    and modify your url to allow strings rather than integers:

    url(r'^profile_view/(?P<username>\w+)/$', 
                           profile_view,
                           name='profile_view'),
    
    0 讨论(0)
  • 2020-12-30 18:41

    Add in the top of the file:

    from django.shortcuts import get_object_or_404
    

    and replace

    u = User.objects.get(pk=user)
    

    with

    u = get_object_or_404(User, <login>=user)
    

    where login is the username field in User model.

    0 讨论(0)
提交回复
热议问题