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

How to pass special characters in the urls in django

假设我想在 url:

中传递用户名
username  = 'kakar@gmail.com'

所以在 url 年代,它是这样的:

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 传递给视图?请帮我解决这个问题。谢谢!

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

from urllib import unquote

user = User.objects.get(username=unquote(user_name))

顺便说一句,据我了解你的 url() 中的正则表达式应该是 [\w@%.]+。普通 \w+ 不匹配 kakar@gmail.comkakar%40gmail.com.

使用w

指定字符串

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

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

对于基于函数的视图:

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...
]

基于函数的视图就差不多了。但我使用的是基于 class 的视图,它们看起来有点不同。这是我为使用基于 class 的视图所做的工作:

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

并且在使用基于 class 的视图时,您的 urls.py:

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