如何在django中的URL中传递特殊字符

时间:2015-01-15 07:45:08

标签: python django django-urls

假设我想在网址中传递用户名:

username  = 'kakar@gmail.com'

所以在网址中,它是这样的:

url(r'(?P<user_name>\w+)/$', 'user_related.views.profile', name='profile'),

并在views.py中获取该用户:

def profile(request, user_name):
    user = User.objects.get(username=user_name)

    return render(request, 'user_profile.html', {'user':user})

但是我收到了一个错误:

User matching query does not exist.

因为django会自动将@转换为%40。如何将实际username传递给视图?请帮我解决这个问题。谢谢!

3 个答案:

答案 0 :(得分:5)

使用标准urllib模块中的unquote函数:

from urllib import unquote

user = User.objects.get(username=unquote(user_name))
是的,据我所知,你的url()中的正则表达式应该是[\w@%.]+。简单\w+kakar@gmail.comkakar%40gmail.com不匹配。

答案 1 :(得分:3)

现有的答案缺少一些东西,但我没有足够的代表来评论或编辑它。这是一个有效的解决方案:

对于基于函数的视图:

views.py中:

# this is incorrect for current versions of Django in the other answer
from urllib.parse import unquote

def profile(request, user_name):
    user = User.objects.get(username=unquote(user_name))
    return render(request, 'user_profile.html', {'user':user})

然后,在 urls.py 中,我们可以完全跳过正则表达式:

from django.urls import path
urlpatterns = [
    path('users/<str:user_name>/', views.profile, name='profile'),
    # ... put more urls here...
]

基于函数的视图几乎就是这样。但我使用的是基于类的视图,看起来有点不同。这是我为使用基于类的视图所做的工作:

views.py中:

from urllib.parse import unquote
from django.views.generic import DetailView

class Profile(DetailView):
    """Display the user's profile"""
    template_name = 'user_profile.html'
    model = User

    def dispatch(self, request, *args, **kwargs):
        self.username = kwargs['user_name']
        return super().dispatch(request, *args, **kwargs)

    def get_object(self, *args, **kwargs):
        try:
            return User.objects.get(username=unquote(self.username))
        except:
            raise Http404

当使用基于类的视图时,您的 urls.py:

from django.urls import path
urlpatterns = [
    path('users/<str:user_name>/', views.Profile.as_view(), name='profile'),
    # ... put more urls here...
]

答案 2 :(得分:0)

使用w

指定字符串

url(r'^url_name/(?P<param_name>[\w\@%-+]+)/$',url_method,name='end_point_name')