I do use the default django.core.context_processors.request
template context processor so I can access request
instance of HttpRequest in my Django templates.
One use is to retrieve original sender url:
import re
nexturl_re = re.compile('\?next=(.+)$')
@register.simple_tag(takes_context=True)
def get_previous_url(context):
try:
return shop_base + \
nexturl_re.search( context['request'].get_full_path() ).group(1)
except (IndexError, AttributeError):
return shop_base + '/'
I do use it to extract an argument from sender url.
The issue is with some views that do http redirects to another views so the original optional parameter after ?next=
is lost.
Is there some way how to keep/pass the original url for specific views ?
For example following url dispatching of smart.smart_add
view does a redirect. It does not accept optional keyword arguments.
from django.conf.urls import patterns
urlpatterns += patterns('satchmo_store.shop.views',
(r'^add/$', 'smart.smart_add', {}, 'satchmo_smart_add'),
Is there some other way than completely rewrite the original view function ?
Thanks.
Update Based on abstractpaper's answer solved the problem as follows:
import re
nexturlopt_re = re.compile('(\?next=.+)$')
class ForwardUrlArguments(object):
def process_response(self, request, response):
if response.status_code in (301, 302, …):
new_location = response.get('Location')
if new_location:
try:
new_location += nexturlopt_re.search(
request.get_full_path() ).group(1)
except (IndexError, AttributeError):
pass
response['Location'] = new_location
return response
from django.utils.decorators import decorator_from_middleware
forward_urlargs = decorator_from_middleware(ForwardUrlArguments)
@forward_urlargs
def account_signin(request):
…
@forward_urlargs
def cart_smart_add(request):
…
@forward_urlargs
def cart_set_quantity(request):
return cart.set_quantity(request) # wrapped a library function
You can write a Middleware to catch HTTP 301 requests and pass on query parameters.