Question

J'essaie d'inverser une URL nommée et d'inclure une requête dedans. Fondamentalement, j'ai modifié la fonction de connexion, et je veux envoyer ?next= en elle.

Voici ce que je fais maintenant: reverse(name) + "?next=" + reverse(redirect)

Voici ce que j'aimerais faire: reverse(name, kwargs = { 'next':reverse(redirect) } )

Mon URL pour la page de connexion (comme un exemple) ressemble à ceci:

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

Alors, comment modifier tout cela (ou l'appeler) pour inclure le suivant sans avoir à le concaténer? Cela ressemble au mieux à une solution incertaine.

Était-ce utile?

La solution

Vous ne pouvez pas capturer des paramètres dans les confs URL, donc votre méthode est correcte.

Je préfère généralement le formatage des chaînes, mais c'est la même chose.
"%s?next=%s" % (reverse(name), reverse(redirect))

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

L'URLCONF recherche par rapport à l'URL demandée, en tant que chaîne Python normale. Cela n'inclut pas les paramètres Get ou Post, ni le nom de domaine.

Autres conseils

Je viens de faire ma propre fonction d'utilité comme celle posée dans la question:

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

Je pense qu'il est préférable d'envelopper la méthode inverse de Django pour exposer cette API. Voici un code simple pour le faire:

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)

Mettez ce code dans une utilité ou une application commune qui ne dépend que de Django, alors au lieu d'importer django.core.urlresolvers.reverse importe simplement myproject.myutils.urlresolvers.reverse

J'étais troublé par la même question et j'ai trouvé cela lien. Apparemment, votre solution n'est pas du tout conçue. Selon la discussion sur les billets, Django ne fournira pas cette fonctionnalité.

Vous pourriez utiliser Urlobject ou rouler.

L'autre moyen est d'utiliser votre propre fonction pour ce faire, d'une manière beaucoup plus propre. Voici celui indiqué dans la discussion

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

Dans le cas de la question, il peut être utilisé de la manière suivante

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

Pour garder la requête en option, vous pouvez envelopper la fonction inverse de Django avec votre propre fonction qui gère également la requête, permettant une autre gestion appropriée de la fonction inverse.

Création d'une demande appropriée - Notez que le query_kwargs est facultatif, donc vous n'avez pas à l'envoyer

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

Dans utils.py fichier (basé sur docs) pour (1.11 et plus?)

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

Dans les URL 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'),

Et avoir accès à la requête

#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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top