67

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

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

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

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

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

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

4

5 回答 5

62

您无法在 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 参数或域名。

于 2011-02-14T17:50:15.843 回答
34

我刚刚制作了自己的实用程序功能,就像问题中提出的那样:

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
于 2013-03-13T15:17:08.357 回答
8

我认为最好封装 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

于 2012-08-28T23:03:57.297 回答
8

我对同样的问题感到困扰并找到了这个链接。显然,您的解决方案设计得还不错。根据票务讨论,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)})
于 2016-02-03T22:59:11.360 回答
2

为了保持查询可选,您可以使用您自己的也处理查询的函数包装 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>
于 2018-02-12T03:34:21.800 回答