【问题标题】:Including a querystring in a django.core.urlresolvers reverse() call在 django.core.urlresolvers reverse() 调用中包含查询字符串
【发布时间】:2011-06-27 02:05:31
【问题描述】:

我正在尝试反转一个命名的 URL 并在其中包含一个查询字符串。基本上我已经修改了登录功能,我想在里面发送?next=

这是我现在正在做的事情:reverse(name) + "?next=" + reverse(redirect)

这是我想做的事情:reverse(name, kwargs = { 'next':reverse(redirect) } )

我的登录页面 URL(仅作为示例)如下所示:

url(r'^login/', custom_login, name = 'login'),

那么我如何修改整个事情(或称之为)以包含下一个而不必连接它?感觉充其量只是一个不确定的解决方案。

【问题讨论】:

    标签: django reverse urlconf


    【解决方案1】:

    您无法在 url confs 中捕获 GET 参数,因此您的方法是正确的。

    我通常更喜欢字符串格式,但它是一样的。
    "%s?next=%s" % (reverse(name), reverse(redirect))

    http://docs.djangoproject.com/en/dev/topics/http/urls/#what-the-urlconf-searches-against

    URLconf 搜索 请求的 URL,作为普通的 Python 细绳。这不包括 GET 或 POST 参数,或者域名。

    【讨论】:

    • 这是错误的。 URL参数需要编码,如"%s?%s" % (reverse(name), urlencode({"next": reverse(redirect)})
    【解决方案2】:

    我认为最好封装 Django 的 reverse 方法来公开这个 API。下面是一些简单的代码:

    from django.core.urlresolvers import reverse as django_reverse
    
    def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
        """
        Wrapper of django.core.urlresolvers.reverse that attaches arguments in kwargs as query string parameters
        """
        if kwargs:
            return '%s?%s' % (django_reverse(viewname, urlconf, args, None, prefix, current_app), \
                            '&'.join(['%s=%s' % (k,v) for k,v in kwargs.items()]))
        else:
            return django_reverse(viewname, urlconf, args, kwargs, prefix, current_app)
    

    将此代码放入仅依赖于 Django 的实用程序或通用应用程序中,然后不要导入 django.core.urlresolvers.reverse,只需导入 myproject.myutils.urlresolvers.reverse

    【讨论】:

      【解决方案3】:

      我刚刚制作了自己的实用函数,就像问题中提出的那样:

      from django.utils.http import urlencode
      
      def my_reverse(viewname, kwargs=None, query_kwargs=None):
          """
          Custom reverse to add a query string after the url
          Example usage:
          url = my_reverse('my_test_url', kwargs={'pk': object.id}, query_kwargs={'next': reverse('home')})
          """
          url = reverse(viewname, kwargs=kwargs)
      
          if query_kwargs:
              return f'{url}?{urlencode(query_kwargs)}'
      
          return url
      

      【讨论】:

      • 在python3中,最快的方法是f'{url}?{urlencode(query_kwargs)}'
      • 不幸的是,这不适用于reverse_lazy,因为它会强制评估:(
      【解决方案4】:

      我被同样的问题困扰,发现了这个link。显然,您的解决方案设计得还不错。根据票务讨论,Django 不会提供此功能。

      您可以使用urlobjectfurl

      另一种方法是使用您自己的函数来执行此操作,以更简洁的方式。这是讨论中所说的

      from django.utils.http import urlencode
      from django.core.urlresolvers import reverse as original_reverse
      
      def reverse(*args, **kwargs):
          get = kwargs.pop('get', {})
          url = original_reverse(*args, **kwargs)
      
          if get:
              url += '?' + urlencode(get)
      
          return url
      

      在问题的情况下,可以这样使用

      from [myfunctions] import reverse
      ...
      reverse('login', get={next: reverse(redirect)})
      

      【讨论】:

        【解决方案5】:

        为了保持查询可选,您可以将 Django 的 reverse 函数包装为您自己的也处理查询的函数,从而允许对 reverse 函数进行其他适当的处理。

        创建正确的请求 - 请注意,query_kwargs 是可选的,因此您不必发送它

        # from a views in views.py
        def sendingView(request, truckID, fleetSlug):
          #in the GET or POST
          return HttpResponseRedirect(reverse('subAppName:urlViewName', 
                                              kwargs={'anyPassedKawrgs':goHere,…},
                                              query_kwargs={'queries': goHere}
                                              ))
        
        # from a template in specificTemplate.html
        <a class="nav-link" href="{% url 'subAppName:urlViewName' kwarg1=kwarg1 kwarg2=kwarg2 … query_kwargs={'dict':here} %}">Link</a>
        
        #from a model in models.py
        class Truck(models.Model):
          name = models.CharField(…)
          def get_absolute_wi_url(self):
            return reverse('subAppName:urlViewName', kwargs={'kwarg1':kwarg1,'kwarg2':kwarg2})
        

        utils.py 文件(基于docs)中(1.11 及更高版本?)

        -myMainApp
          -apps
          -static
          ...
          -utils
            -__init__.py
            -utils.py
        
        from django.core.urlresolvers import reverse as django_reverse
        
        def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None, query_kwargs=None):
          """
          Wrapper of django.core.urlresolvers.reverse that attaches arguments in kwargs as query string parameters
          """
          if query_kwargs:
            return '%s?%s' % (django_reverse(viewname, urlconf, args, kwargs, current_app), \
                            '&'.join(['%s=%s' % (k,v) for k,v in query_kwargs.items()]))
          else:
            return django_reverse(viewname, urlconf, args, kwargs, current_app)
        

        在 urls 中配置 urls.py

        app_name = 'subAppName'
        urlpatterns = [
          url(r'^(?P<kawrg1>[a-zA-Z0-9]+)/(?P<kawrg2>[a-zA-Z0-9]+)/path/to/here/$', views.urlViewFunctionName, name='urlViewName'),
        

        并获得对查询的访问权

        #in a view
        def urlViewFunctionName(request, kwarg1, kwarg2):   
          if request.GET.get('submittedData'):
            submittedQuery = request.GET.get('submittedData')
        else:
          submittedQuery = None
        return render(request, 'trucks/weeklyInspectionSuccess.html', {
          'truck': truck,
          'submittedQuery': submittedQuery
        })
        
        #in a template
        <div class="container">  
          Success for {{kwarg1}}
          {{submittedQuery}}
        </div>
        

        【讨论】:

          猜你喜欢
          • 2011-05-14
          • 2011-02-05
          • 1970-01-01
          • 2011-03-30
          • 1970-01-01
          • 1970-01-01
          • 2011-02-19
          • 2023-04-10
          • 1970-01-01
          相关资源
          最近更新 更多