在request.GET中捕获url参数

sut*_*tee 414 django rest url

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

我想学习如何在没有库的情况下这样做,这样我就能更好地了解Django.

cam*_*lan 609

当url像:domain/search/?q=haha,那么你会使用request.GET.get('q', '').

q是您想要的参数,''如果q找不到则是默认值.

但是,如果您只是配置您的URLconf,那么您的捕获regex将作为参数(或命名参数)传递给函数.

如:

(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),
Run Code Online (Sandbox Code Playgroud)

然后在你的views.py你会有

def profile_page(request, username):
    # Rest of the method
Run Code Online (Sandbox Code Playgroud)

  • '?param ='是Django识别参数的唯一方法吗?有没有办法在HTTP.GET中使用URLconf?我想做/ param/2. (10认同)
  • 基于类的观点怎么样? (7认同)
  • 对于基于类的视图,您可以使用`self.kwargs ['parameter']` (5认同)
  • 检查我的回复的第二部分有关您的URLconf和正则表达式捕获. (3认同)
  • 没问题.如果您使用GET提交表单,请使用request.GET,如果您使用POST提交表单,请使用request.POST,如果您只想将URL配置为具有可变部分,那么它是一个URLconf/view参数. (2认同)

aka*_*ola 319

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

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

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

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')
Run Code Online (Sandbox Code Playgroud)

作为旁注,您将找到请求方法(在这种情况下"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
  • 制作人性化的URL,避免使用ID号并使用日期,类别和/或slu :: /blog/post/2008/09/30/django-urls/

  • 这是一个非常好的答案.它确实帮助我更好地理解Django. (17认同)
  • 如何在不提及名称的情况下获取所有参数值 (2认同)

Dad*_*ane 49

使用GET

request.GET["id"]
Run Code Online (Sandbox Code Playgroud)

使用POST

request.POST["id"]
Run Code Online (Sandbox Code Playgroud)

  • 虽然这适用于现有密钥,但camflan和akaihola的答案使用.get()来避免在丢失密钥的情况下出现"KeyError"异常.做同样的事情是明智的(例如`request.POST.get('id','')`). (24认同)

小智 22

def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..
Run Code Online (Sandbox Code Playgroud)


DrK*_*liN 17

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

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

这基本上意味着www.example.com/<username>.请务必将其放置在你的URL条目的结束,否则,很容易造成下面下面的URL条目,即访问它们的一个冲突将会给你不错的错误:User matching query does not exist.

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

  • 另外,在这种情况下,您可能需要检查用户名是否与其他网址冲突. (2认同)

Ole*_*røm 14

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


小智 12

如果您的网址如下所示,您有两种常用的方法:

https://domain/method/?a=x&b=y
Run Code Online (Sandbox Code Playgroud)

V1:

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

key_a = request.GET['a']
Run Code Online (Sandbox Code Playgroud)

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

V2:

如果您的钥匙是可选的:

request.GET.get('a')
Run Code Online (Sandbox Code Playgroud)

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


Ars*_*dev 11

如果您不知道参数的名称并想使用所有参数,您可以使用request.GET.keys()ordict(request.GET)函数


mdc*_*dcg 10

这些查询目前以两种方式完成。如果要访问查询参数 (GET),可以查询以下内容:

http://myserver:port/resource/?status=1
Run Code Online (Sandbox Code Playgroud)
request.query_params.get('status', None) => 1
Run Code Online (Sandbox Code Playgroud)

如果要访问POST传递的参数,需要这样访问:

request.data.get('role', None)
Run Code Online (Sandbox Code Playgroud)

使用 'get()' 访问字典 (QueryDict),您可以设置默认值。在上述情况下,如果未通知 'status' 或 'role',则值为 None。


Eri*_*ews 9

我想在这里添加一些我自己的选项。有人会想知道如何在urls.py中设置路径,例如

domain/search/?q=CA
Run Code Online (Sandbox Code Playgroud)

这样我们就可以调用查询。

事实是,没有必要在urls.py中设置这样的路由。您需要设置的只是urls.py中的路由

urlpatterns = [
    path('domain/search/', views.CityListView.as_view()),
]
Run Code Online (Sandbox Code Playgroud)

当您输入http:// servername:port / domain / search /?q = CA时。查询部分“?q = CA”将自动保留在哈希表中,尽管您可以参考

request.GET.get('q', None).
Run Code Online (Sandbox Code Playgroud)

这是一个例子(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
Run Code Online (Sandbox Code Playgroud)

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

http://servername:port/domain/search/?q=CA
Run Code Online (Sandbox Code Playgroud)

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

http://servername:port/domain/search/?q="CA"
Run Code Online (Sandbox Code Playgroud)


jam*_*ing 8

这不正是你问什么,但这个片段是管理有帮助query_stringstemplates.


Mar*_*nte 8

如果您只能访问视图对象,则可以通过以下方式获取 URL 路径中定义的参数:

view.kwargs.get('url_param')
Run Code Online (Sandbox Code Playgroud)

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

request.resolver_match.kwargs.get('url_param')
Run Code Online (Sandbox Code Playgroud)

在 Django 3 上测试。


Oma*_*gdy 7

视图.py

from rest_framework.response import Response

def update_product(request, pk):
    return Response({"pk":pk})
Run Code Online (Sandbox Code Playgroud)

pk表示Primary_key

urls.py

from products.views import update_product
from django.urls import path

urlpatterns = [
    ...,
    path('update/products/<int:pk>', update_product)
]
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是编写路径的最干净的方式,您可以扩展更多关于答案的内容,例如解释一些关于文档的可选参数并解释一些添加的代码片段,只是向框架中的新人解释一下。 (2认同)

Ahm*_*hab 6

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

Run Code Online (Sandbox Code Playgroud)

你说它返回空查询字典

我认为你需要调整你的 url 以接受必需或可选的 args 或 kwargs Django 通过 regex 为你提供了所需的所有功能,例如:

url(r'^project_config/(?P<product>\w+)/$', views.foo),

Run Code Online (Sandbox Code Playgroud)

有关此内容的更多信息,请访问django-Optional-url-parameters


小智 5

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

在 URL 配置中:

urlpatterns = [path('runreport/<str:queryparams>', views.get)]
Run Code Online (Sandbox Code Playgroud)

在意见中:

list2 = queryparams.split("&")
Run Code Online (Sandbox Code Playgroud)