【问题标题】:django username in url, instead of idurl中的django用户名,而不是id
【发布时间】:2011-03-02 02:00:08
【问题描述】:

在一个迷你虚拟社区中,我有一个 profile_view 功能,这样我就可以查看任何注册用户的个人资料。配置文件视图函数将配置文件所属的用户的 id 作为参数,因此,例如,当我想访问用户 2 的配置文件时,我这样称呼它: http://127.0.0.1:8000/accounts/profile_view/2/

我的问题是我想在 url 中有用户名,而不是 id。 我尝试按如下方式修改我的代码,但它仍然无法正常工作。这是我的代码:

查看:

def profile_view(request, user):
        u = User.objects.get(pk=user)
        up = UserProfile.objects.get(created_by = u)
        cv = UserProfile.objects.filter(created_by = User.objects.get(pk=user))
        blog = New.objects.filter(created_by = u) 
        replies = Reply.objects.filter(reply_to = blog)
        vote = Vote.objects.filter(voted=blog)
        following = Relations.objects.filter(initiated_by = u)
        follower = Relations.objects.filter(follow = u)
    return render_to_response('profile/publicProfile.html', {
        'vote': vote,
        'u':u,  
        'up':up, 
        'cv': cv, 
        'ing': following.order_by('-date_initiated'),  
        'er': follower.order_by('-date_follow'),
        'list':blog.order_by('-date'),
        'replies':replies
        }, 
        context_instance=RequestContext(request)) 

还有我的网址:

urlpatterns = patterns('',
                        url(r'^profile_view/(?P<user>\d+)/$', 
                           profile_view,
                           name='profile_view'),

提前致谢!

【问题讨论】:

    标签: django url friendly-url


    【解决方案1】:

    你没有展示你已经尝试过什么,或者你在哪里遇到了麻烦。毕竟,这相当简单 - 只需将用户名字符串而不是整数传递给函数,然后根据它进行查找。

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

    并修改您的网址以允许使用字符串而不是整数:

    url(r'^profile_view/(?P<username>\w+)/$', 
                           profile_view,
                           name='profile_view'),
    

    【讨论】:

    • 根据我在 django/contrib/auth/forms.py 中看到的内容,我认为用于获取用户名的更好的正则表达式是 (?P[\w.@+-]+ )
    • 如果用户名是电子邮件并且您不希望此信息公开怎么办?您可以使用用户的名字和姓氏,但这可能会重复,所以我认为我们应该在 ID 上添加一个 ID 或哈希。
    【解决方案2】:

    这是我使用基于类的通用视图和使用 slug 的方法。它非常简单,在 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()),
    )
    

    现在您可以访问accounts/profile/id/123/accounts/profile/username/gertvdijk/ 等用户。

    这里发生了什么?

    • 通常需要的pk URL 参数在URL 模式中被省略并替换为slug。这被视图所接受,因为...
    • DetailView(或任何其他基于 SingleObjectMixin 的视图)正在使用 slug 参数通过使用 model = Userslug_field = "username"User.username 上查找对象。 (docs)
    • 由于 slug 字段是可选的,因此仅使用 pk 参数也可以愉快地为视图提供服务。

    【讨论】:

    • 如果用户名有任何 .@+ 会发生什么,因为这些不是 slug 中的有效字符?
    • 在将 User 扩展到 UserProfile 的情况下如何执行此操作(您知道为用户获取更多字段)。 User 模型具有“用户名”字段,但 UserProfile 模型具有我想要显示的自定义字段。
    • @RicardoGonzales 这很简单...更改modelslug_field。适用于所有 Django 模型,此配方,而不仅仅是 Users。
    【解决方案3】:

    在 urls.py 中

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

    使用基于类的视图。

    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!!")
    

    我已经在 Django 2.1 中测试过。

    【讨论】:

      【解决方案4】:

      在文件顶部添加:

      from django.shortcuts import get_object_or_404
      

      替换

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

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

      其中 login 是 User 模型中的用户名字段。

      【讨论】:

      • 我已经按照你说的做了替换,它说我在“u = User.objects.get(=user)”行有一个语法错误
      • 用用户名字段的名称替换登录名。我不知道那里是怎么称呼的。另请查看其他答案并修复网址。
      【解决方案5】:

      对于 Django 2.0 及更高版本:

      path(‘profile/<username>/, views.profile, name=‘profile’),
      

      【讨论】:

        猜你喜欢
        • 2017-01-26
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多