【发布时间】:2010-09-14 02:39:43
【问题描述】:
我目前正在定义正则表达式以捕获 URL 中的参数,如教程中所述。如何从 URL 访问参数作为 HttpRequest 对象的一部分?
我的HttpRequest.GET 当前返回一个空的QueryDict 对象。
我想学习如何在没有库的情况下做到这一点,以便更好地了解 Django。
【问题讨论】:
我目前正在定义正则表达式以捕获 URL 中的参数,如教程中所述。如何从 URL 访问参数作为 HttpRequest 对象的一部分?
我的HttpRequest.GET 当前返回一个空的QueryDict 对象。
我想学习如何在没有库的情况下做到这一点,以便更好地了解 Django。
【问题讨论】:
当 URL 类似于 domain/search/?q=haha 时,您将使用 request.GET.get('q', '')。
q 是你想要的参数,如果没有找到q,'' 是默认值。
但是,如果您只是配置 URLconf**,那么您从 regex 捕获的内容将作为参数(或命名参数)传递给函数。
如:
(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),
然后在您的views.py 中您将拥有
def profile_page(request, username):
# Rest of the method
【讨论】:
self.kwargs['parameter']
为了澄清camflan 的explanation,假设你有
url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
http://domain/user/thaiyoshi/?message=Hi 的传入请求
URL 调度程序规则将捕获部分 URL 路径(此处为 "user/thaiyoshi/")并将它们与请求对象一起传递给视图函数。
解析查询字符串(此处为message=Hi)并将参数存储为QueryDict 中的request.GET。没有对 HTTP GET 参数进行进一步的匹配或处理。
此视图函数将使用从 URL 路径中提取的两个部分和一个查询参数:
def profile_page(request, username=None):
user = User.objects.get(username=username)
message = request.GET.get('message')
作为附注,您可以在request.method 中找到请求方法(在本例中为"GET",对于提交的表单通常为"POST")。在某些情况下,检查它是否符合您的预期会很有用。
更新:在决定是否使用 URL 路径或查询参数来传递信息时,以下可能会有所帮助:
/blog/post/15/(不是/blog/posts/?id=15)/blog/post/15/?show_comments=1 或 /blog/posts/2008/?sort_by=date&direction=desc
/blog/post/2008/09/30/django-urls/
【讨论】:
使用 GET
request.GET["id"]
使用 POST
request.POST["id"]
【讨论】:
KeyError 异常。这样做是明智的(例如request.POST.get('id', ''))。
有人会好奇如何在文件urls.py中设置路径,比如
domain/search/?q=CA
以便我们可以调用查询。
事实上,不需要在文件urls.py中设置这样的路由。您只需要在 urls.py 中设置路由:
urlpatterns = [
path('domain/search/', views.CityListView.as_view()),
]
当你输入 http://servername:port/domain/search/?q=CA.查询部分 '?q=CA' 将自动保留在您可以参考的哈希表中
request.GET.get('q', None).
这是一个例子(文件views.py)
class CityListView(generics.ListAPIView):
serializer_class = CityNameSerializer
def get_queryset(self):
if self.request.method == 'GET':
queryset = City.objects.all()
state_name = self.request.GET.get('q', None)
if state_name is not None:
queryset = queryset.filter(state__name=state_name)
return queryset
另外,当你在 URL 中写查询字符串时:
http://servername:port/domain/search/?q=CA
不要将查询字符串用引号引起来。例如,
http://servername:port/domain/search/?q="CA"
【讨论】:
def some_view(request, *args, **kwargs):
if kwargs.get('q', None):
# Do something here ..
【讨论】:
对于只有request 对象的情况,您可以使用request.parser_context['kwargs']['your_param']
【讨论】:
如果你的 URL 看起来像这样,你有两种常用的方法:
https://domain/method/?a=x&b=y
版本 1:
如果特定的密钥是强制性的,您可以使用:
key_a = request.GET['a']
如果键存在则返回值a,如果不存在则返回异常。
版本 2:
如果您的密钥是可选的:
request.GET.get('a')
您可以尝试不带任何参数,这不会崩溃。
所以你可以用try: except: 包装它并在示例中返回HttpResponseBadRequest()。
这是一种简化代码复杂度的简单方法,无需使用特殊的异常处理。
【讨论】:
我想分享一个可以节省您一些时间的提示。
如果您打算在 urls.py 文件中使用类似的内容:
url(r'^(?P<username>\w+)/$', views.profile_page,),
这基本上意味着www.example.com/<username>。请务必将它放在您的 URL 条目的末尾,否则,它很容易与下面的 URL 条目发生冲突,即访问其中一个将给您一个不错的错误:@ 987654324@
我自己也刚刚经历过;希望有帮助!
【讨论】:
这些查询目前以两种方式完成。如果要访问查询参数 (GET),可以查询以下内容:
http://myserver:port/resource/?status=1
request.query_params.get('status', None) => 1
如果要访问POST传递的参数,需要这样访问:
request.data.get('role', None)
使用'get()'访问字典(QueryDict),你可以设置一个默认值。在上述情况下,如果 'status' 或 'role' 没有被告知,则值为 None。
【讨论】:
这并不完全符合您的要求,但this snippet 有助于管理templates 中的query_strings。
【讨论】:
如果你只能访问视图对象,那么你可以通过这种方式获取URL路径中定义的参数:
view.kwargs.get('url_param')
如果您只能访问请求对象,请使用以下内容:
request.resolver_match.kwargs.get('url_param')
在 Django 3 上测试。
【讨论】:
如果你不知道 params 的名称并且想全部使用它们,你可以使用 request.GET.keys() 或 dict(request.GET) 函数
【讨论】:
这是另一个可以实施的替代解决方案:
在网址配置中:
urlpatterns = [path('runreport/<str:queryparams>', views.get)]
在视图中:
list2 = queryparams.split("&")
【讨论】:
您不妨检查 request.META 字典以访问许多有用的东西,例如 PATH_INFO,QUERY_STRING
# for example
request.META['QUERY_STRING']
# or to avoid any exceptions provide a fallback
request.META.get('QUERY_STRING', False)
你说它返回空查询字典
我认为您需要调整您的网址以接受必需或可选的 args 或 kwargs Django 使用正则表达式为您提供所需的所有功能,例如:
url(r'^project_config/(?P<product>\w+)/$', views.foo),
【讨论】:
from rest_framework.response import Response
def update_product(request, pk):
return Response({"pk":pk})
pk 表示 primary_key。
from products.views import update_product
from django.urls import path
urlpatterns = [
...,
path('update/products/<int:pk>', update_product)
]
【讨论】:
def update_product(request, pk=None): pk 是可选的...
update/products//,最后带有双斜杠,因为它是空的。那么路径应该是这样的:path('update/products/<int:pk>', update_product),而不是这样的:path('update/products/<int:pk>/', update_product),我已经更新了。我删除了问题答案中的最后一个斜杠。差异是最后一个斜线。 :) :)