【问题标题】:Capturing URL parameters in request.GET在 request.GET 中捕获 URL 参数
【发布时间】:2010-09-14 02:39:43
【问题描述】:

我目前正在定义正则表达式以捕获 URL 中的参数,如教程中所述。如何从 URL 访问参数作为 HttpRequest 对象的一部分?

我的HttpRequest.GET 当前返回一个空的QueryDict 对象。

我想学习如何在没有库的情况下做到这一点,以便更好地了解 Django。

【问题讨论】:

    标签: django url rest


    【解决方案1】:

    当 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
    

    【讨论】:

    • 是 '?param=' Django 识别参数的唯一方法吗?有没有办法将 URLconf 与 HTTP.GET 一起使用?我想做 /param/2。
    • 检查我回复的第二部分关于您的 URLconf 和正则表达式捕获。
    • 没问题。如果您使用 GET 提交表单,请使用 request.GET,如果您使用 POST 提交表单,请使用 request.POST,如果您只想将 URL 配置为具有可变部分,那么它是 URLconf/view 参数。
    • 基于类的视图呢?
    • 对于基于类的视图,您可以使用self.kwargs['parameter']
    【解决方案2】:

    为了澄清camflanexplanation,假设你有

    • 规则url(regex=r'^user/(?P&lt;username&gt;\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 路径或查询参数来传递信息时,以下可能会有所帮助:

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

    【讨论】:

    • 这是一个写得很好的答案。它确实帮助我更好地理解了 Django。
    • 如何在不提及名称的情况下获取所有参数值
    • @numerah request.GET 是一个 Python 字典。你可以例如遍历 request.GET.items()。
    • 有什么理由喜欢遵循更新中的习惯? (何时使用 URL 路径与 GET 参数)
    • @m0etaz 真是个好问题。我想你很难找到这个概念的起源。根据我的经验,这几乎是以部落的方式传给我的,我也很想找到起源。
    【解决方案3】:

    使用 GET

    request.GET["id"]
    

    使用 POST

    request.POST["id"]
    

    【讨论】:

    • 虽然这适用于现有密钥,但 camflan 和 akaihola 的答案已使用 .get() 来避免在缺少密钥的情况下出现KeyError 异常。这样做是明智的(例如request.POST.get('id', ''))。
    【解决方案4】:

    有人会好奇如何在文件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"
    

    【讨论】:

    • 嗨,埃里克!我是 Django 的新手。您能否进一步了解“queryset = queryset.filter(state__name=state_name)”。 state__name 中的双下划线是什么意思。
    • 这里的“state”是一个表,“name”是这个表中的一个字段。在 Django 的过滤器中,state__name 会引用“state”表中“name”字段的值。
    【解决方案5】:
    def some_view(request, *args, **kwargs):
        if kwargs.get('q', None):
            # Do something here ..
    

    【讨论】:

      【解决方案6】:

      对于只有request 对象的情况,您可以使用request.parser_context['kwargs']['your_param']

      【讨论】:

        【解决方案7】:

        如果你的 URL 看起来像这样,你有两种常用的方法:

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

        版本 1:

        如果特定的密钥是强制性的,您可以使用:

        key_a = request.GET['a']
        

        如果键存在则返回值a,如果不存在则返回异常

        版本 2:

        如果您的密钥是可选的:

        request.GET.get('a')
        

        您可以尝试不带任何参数,这不会崩溃。 所以你可以用try: except: 包装它并在示例中返回HttpResponseBadRequest()。 这是一种简化代码复杂度的简单方法,无需使用特殊的异常处理。

        【讨论】:

        • 如何从模板中检测查询参数?
        【解决方案8】:

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

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

        这基本上意味着www.example.com/&lt;username&gt;。请务必将它放在您的 URL 条目的末尾,否则,它很容易与下面的 URL 条目发生冲突,即访问其中一个给您一个不错的错误:@ 987654324@

        我自己也刚刚经历过;希望有帮助!

        【讨论】:

        • 另外,在这种情况下,您可能需要检查用户名是否与其他 url enrties 冲突。
        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

          这并不完全符合您的要求,但this snippet 有助于管理templates 中的query_strings

          【讨论】:

            【解决方案11】:

            如果你只能访问视图对象,那么你可以通过这种方式获取URL路径中定义的参数:

            view.kwargs.get('url_param')
            

            如果您只能访问请求对象,请使用以下内容:

            request.resolver_match.kwargs.get('url_param')
            

            在 Django 3 上测试。

            【讨论】:

              【解决方案12】:

              如果你不知道 params 的名称并且想全部使用它们,你可以使用 request.GET.keys()dict(request.GET) 函数

              【讨论】:

                【解决方案13】:

                这是另一个可以实施的替代解决方案:

                在网址配置中:

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

                在视图中:

                list2 = queryparams.split("&")
                

                【讨论】:

                • 帮我理解了,我可以通过“”传递int
                【解决方案14】:

                您不妨检查 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),
                
                

                更多信息请访问django-optional-url-parameters

                【讨论】:

                  【解决方案15】:

                  views.py

                  from rest_framework.response import Response
                  
                  def update_product(request, pk):
                      return Response({"pk":pk})
                  

                  pk 表示 primary_key

                  urls.py

                  from products.views import update_product
                  from django.urls import path
                  
                  urlpatterns = [
                      ...,
                      path('update/products/<int:pk>', update_product)
                  ]
                  

                  【讨论】:

                  • 我认为这是编写路径的最干净的方法,您可以扩展更多关于答案的信息,例如解释一下文档的可选参数并解释一下添加的代码片段,只是为了框架中的新手。
                  • 感谢您的评论。我真的很感激。 :) .URL 参数不能是可选的(据我所知)。因为它们指定了将执行哪个函数。可选的是请求正文中的查询参数和数据。这可以通过序列化程序(在 Django REST 框架中)进行控制。 @allexiusw
                  • 当然可以,你必须使用:def update_product(request, pk=None): pk 是可选的...
                  • 你是对的。 :) :) 但是,恐怕这可能会创建一个像这样的端点:update/products//,最后带有双斜杠,因为它是空的。那么路径应该是这样的:path('update/products/&lt;int:pk&gt;', update_product),而不是这样的:path('update/products/&lt;int:pk&gt;/', update_product),我已经更新了。我删除了问题答案中的最后一个斜杠。差异是最后一个斜线。 :) :)
                  • 我很高兴你让我意识到这一点。 :) :) 我以前没有意识到。 :) :)
                  猜你喜欢
                  • 2017-01-22
                  • 1970-01-01
                  • 2013-02-06
                  • 2021-09-28
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-12-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多