捕获request.GET中的url参数


457

如教程中所述,我目前正在定义正则表达式以捕获url中的参数。我如何从url作为HttpRequest对象的一部分访问参数?我HttpRequest.GET当前返回一个空QueryDict对象。

我想学习如何在没有库的情况下执行此操作,以便更好地了解Django。

Answers:


659

当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

10
Django识别参数的唯一方法是'?param ='吗?有没有办法将URLconf与HTTP.GET一起使用?我想做/ param / 2。
sutee

3
检查我的答复的第二部分有关您的URLconf和正则表达式捕获。
camflan

2
没问题。如果使用GET提交表单,请使用request.GET;如果使用POST提交表单,请使用request.POST;如果只想将URL配置为具有可变部分,则使用URLconf / view参数。
camflan

10
基于类的视图呢?
用户

8
可以使用基于类的视图self.kwargs['parameter']
Royendgel Silberie

335

为了澄清camflan的解释,让我们假设您有

  • 规则 url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • 传入请求 http://domain/user/thaiyoshi/?message=Hi

URL调度程序规则将捕获URL 路径的一部分(此处为"user/thaiyoshi/"),并将它们与请求对象一起传递给view函数。

message=Hi解析查询字符串(此处),并将参数存储为QueryDictin request.GET。没有完成对HTTP GET参数的进一步匹配或处理。

此视图函数将使用从URL路径提取的两个部分以及一个查询参数:

def profile_page(request, username=None):
    user = User.objects.get(username=username)
    message = request.GET.get('message')

另外,您会在中找到request方法(在这种情况下"GET",通常是针对提交的表单"POST"request.method。在某些情况下,检查它是否符合您的期望很有用。

更新:在决定是否使用URL路径或查询参数来传递信息时,以下内容可能会有所帮助:

  • 使用URL路径唯一标识资源,例如/blog/post/15/(不是/blog/posts/?id=15
  • 使用查询参数来更改资源的显示方式,例如/blog/post/15/?show_comments=1/blog/posts/2008/?sort_by=date&direction=desc
  • 为了使网址友好,请避免使用ID号,并使用例如日期,类别和/或标签: /blog/post/2008/09/30/django-urls/

17
这是一个写得很好的答案。它肯定有助于我更好地了解Django。
2012年

2
我们如何获得所有参数值而又不提及名称
numerah 2014年

@numerah request.GET是Python字典。您可以例如通过request.GET.items()进行迭代。
akaihola

完美的答案。
杰伊·盖斯

1
有什么理由更喜欢遵循更新中写的习惯?(何时使用URL路径vs GET参数)
m0etaz

55

使用GET

request.GET["id"]

使用POST

request.POST["id"]

27
虽然这适用于现有键,但是camflan和akaihola的答案使用.get()来避免KeyError键丢失时的异常。这样做是明智的(例如request.POST.get('id', ''))。
2015年

25
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..


20

我想在这里添加一些我自己的选项。有人会想知道如何在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

此外,当您在网址中编写查询字符串时

http://servername:port/domain/search/?q=CA

不要将查询字符串用引号引起来,例如

http://servername:port/domain/search/?q="CA"

嗨,埃里克!我是Django的新手。您能否进一步说明“ queryset = queryset.filter(state__name = state_name)”。state__name中的双下划线表示什么。
Subbu

1
这里的“状态”是一个表,“名称”是该表中的文件。在Django的过滤器中,state__name将引用“状态”表中字段“名称”的值。
埃里克·安德鲁斯

与其他人相比,这一人有效。
锡比什

17

我想分享一个技巧,可以节省您一些时间。
如果您打算在urls.py文件中使用类似这样的内容:

url(r'^(?P<username>\w+)/$', views.profile_page,),

这基本上意味着www.example.com/<username>。请务必将其放置在你的URL条目的结束,否则,很容易出现低于后面的URL条目引起冲突,IE浏览器访问他们中的一个让你漂亮的错误:User matching query does not exist.

我刚刚经历了它自己; 希望能帮助到你!


2
另外,在这种情况下,您可能需要检查用户名是否与其他URL属性不冲突。
DrKaoliN

13

如果您的网址看起来像这样,您有两种常用的方法:

https://domain/method/?a=x&b=y

v1:

如果必须使用特定密钥,则可以使用:

key_a = request.GET['a']

这将返回aif键存在的值,如果不存在则返回Exception。

v2:

如果您的键是可选的:

request.GET.get('a')

您可以尝试不使用任何参数而不会崩溃。因此,您可以将其包装起来try: except:并返回HttpResponseBadRequest()示例。这是一种无需使用特殊的Exceptions处理就可以简化代码的简单方法。


如何从模板中检测查询参数?
Akin Hwan


5

这些查询当前以两种方式完成。如果要访问查询参数(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。


0

这是可以实现的另一种替代解决方案:

在url配置中。:

urlpatterns = [path('runreport/<str:queryparams>', views.get)]

在意见:

list2 = queryparams.split("&")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.