webentwicklung-frage-antwort-db.com.de

Inkludiere einen Querstring in einem Aufruf von Django.core.urlresolvers reverse ()

Ich versuche, eine benannte URL umzukehren und eine Querzeichenfolge hinzuzufügen. Grundsätzlich habe ich die Login-Funktion geändert und möchte ?next= darin senden.

Folgendes mache ich jetzt: reverse(name) + "?next=" + reverse(redirect)

Folgendes möchte ich tun: reverse(name, kwargs = { 'next':reverse(redirect) } )

Meine URL für die Anmeldeseite (nur als Beispiel) sieht folgendermaßen aus:

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

Wie kann ich also das Ganze ändern (oder so nennen), dass es das nächste enthält, ohne es verketten zu müssen? Es fühlt sich bestenfalls als eine unangenehme Lösung an.

36
Brian Hicks

Sie können keine GET-Parameter in der URL confs erfassen, daher ist Ihre Methode korrekt.

Ich bevorzuge im Allgemeinen die Formatierung von Zeichenfolgen, aber es ist dasselbe.
"%s?next=%s" % (reverse(name), reverse(redirect))

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

Die URLconf durchsucht die angeforderte URL als normale Python Zeichenfolge. Dies schließt weder GET noch POST Parameter noch den Domainnamen ein.

43

Ich habe gerade meine eigene Utility-Funktion erstellt, wie sie in der Frage gestellt wurde:

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 u'%s?%s' % (url, urlencode(query_kwargs))

    return url
22
Daniel Backman

Ich denke, es ist besser, die umgekehrte Methode von Django zu verwenden, um diese API verfügbar zu machen. Hier ist ein einfacher Code, um es zu tun:

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)

Fügen Sie diesen Code in ein Hilfsprogramm oder eine allgemeine Anwendung ein, die nur von Django abhängt, und importieren Sie statt Django.core.urlresolvers.reverse einfach myproject.myutils.urlresolvers.reverse

6
Alan Illing

Ich war mit der gleichen Frage beunruhigt und fand diese Verbindung . Anscheinend ist Ihre Lösung überhaupt nicht schlecht konzipiert. Laut Ticketdiskussion stellt Django diese Funktionalität nicht zur Verfügung.

Sie könnten urlobject oder furl verwenden.

Die andere Möglichkeit besteht darin, Ihre eigene Funktion dafür auf viel sauberere Weise zu verwenden. Hier ist der in der Diskussion angegebene

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

Im Fall der Frage kann es folgendermaßen verwendet werden

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

Um die Abfrage optional zu halten, können Sie die Umkehrfunktion von Django mit Ihrer eigenen Funktion umschließen, die auch die Abfrage verarbeitet.

Erstellen einer ordnungsgemäßen Anforderung - Beachten Sie, dass der query_kwargs optional ist, sodass Sie ihn nicht senden müssen 

# 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})

In utils.py-Datei (basierend auf docs ) für (1.11 und höher?)

-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)

In den URLs conf 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'),

Und Zugriff auf die Abfrage erhalten

#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>
0
chris Frisina