using HttpResponseRedirect - python

In one of my view function, under certain condition I want to redirect to another URL.
So I am doing
return HttpResponseRedirect(reverse(next_view, kwargs={'name': name1}))
Now I have another view function like
def next_view(request, name):
I also put following line in relevant urls.py file
from wherever import next_view
urlpatterns = patterns("",
url(r"^next_view/(?P<name>w+)/", next_view, name="next_view"),
)
This does not work, I get
Reverse for 'next_view' with arguments '()' and keyword arguments '{'name': u'test'}' not found.

I'm guessing that the regex isn't matching properly. How about:
r"^next_view/(?P<name>\w+)/"
Note the backslash before the 'w'.

For urls.py you want to add the backslash before the w+ and also add a $ sign at then end of the URL so that any other URL's joined onto this will be accepted:
urlpatterns = patterns("",
url(r"^next_view/(?P<name>\w+)/$", next_view, name="next_view"),
)
For views.py you want to add parenthesis around your view name:
def example_view(self):
# view code
return HttpResponseRedirect(reverse('next_view', kwargs={'name': name1}))

Related

Django Regular expression many slugs

I have the regular expression in my url that accepts pass one slug to my view, exemple:
127.0.0.1/cart/product_slug1
But I need a regex that accept pass one or more slugs, example:
127.0.0.1/cart/product_slug1/product_slug2/product_slug3/.../product_slugN
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(
r'^cart/add/(?P<slug>[\w_-]+)/$', views.create_cartitem,
name='create_cartitem'
),
It's possible send many slugs?
[UPDATE]: It seems that you cannot do that. Instead, you can place a catch all pattern and capture the whole url. Then inside your views you can split it by / and get the parameters you want. Something like this:
urlpatterns = [
url(
r'^cart/add/(?P<slugs>[\w_/-]+)/$', views.create_cartitem, name='create_cartitem'
),
And then in your views, do this:
def my_view(request, slugs):
slugs = slugs.split('/')
# now slugs is a list of strings
Note, however, that this is error prone since both cart/add/h/e/l/l/o and cart/add/hell//o//to/you are valid.
-- OLD ANSWER --
Sure you can, but you cannot use both named captured parameters with unnamed ones.
So, change your urls.py to this:
urlpatterns = [
url(
r'^cart/add/([\w_-]+)/([\w_-]+/)*$', views.create_cartitem, name='create_cartitem'
),
And inside your views.py, instead of kwargs (like slug you already have) you must use args (positional arguments, now you're gonna have a list of slugs). Like this:
def my_view(request, *args):
for arg in args:
print(arg)
Now if you type 127.0.0.1:8000/cart/add/argv/argvv/argvvv/, inside your views you get them as a list ['argv', 'argvv', 'argvvv'].

Django - How to add on to reverse urlresolver properly

Suppose I have this:
from django.core.urlresolvers import reverse
url = reverse('account-list')
Assume this leads to the URL: `/account/list/'
How do I add on to the URL? I want to make that URL this: /account/list/1 (adding a pk value to the end of it). I know over here: Including a querystring in a django.core.urlresolvers reverse() call it explains how to add GET parameters (e.g. ?pk=1 but I want to know if there is a proper way for me to add on to the URL (not using GET parameters)).
I'm using DRF routers: router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) and the user-detail view takes a pk value. So I want to do url = reverse('user-list') with /1 appended to the end of it.
If you are interested specifically in the detail view then you shouldn't use account-list. Assuming you have a separate account-detail view (Django Rest Framework will create these for you as well when you are using default ModelViewSets, just the same as it did with account-list):
from django.core.urlresolvers import reverse
u = reverse('account-detail', args=[1])
would be the proper way to go about this if I understand your question correctly.
You can also handle named URL parameters. For the following URL rule with a slug parameter:
url(r'/accounts/(?<slug>[a-fA-F0-9]+)/', name='account-detail', ...)
here's how you'd reverse the detail view for the account with a slug equal to something:
from django.core.urlresolvers import reverse
u = reverse('account-detail', kwargs={'slug': 'something'})

Dynamic Url's in Django

So I have a list of items and I want to have all of the items direct the user to a standard info page about that item when clicked. I don't full understand the dynamic url system in django. My html file for the content is called detail.html. The goal is to click a movie item, and be directed to a page title "blahblah.com/specific_movie_title"
In views.py I have:
def detail(reuqest, movie_title):
moviePage = Movie.objects.get(pk=movie_title)
return render_to_response('detail.html', {'detail':moviePage, RequestContext(request))
In the urls.py the line I have to correspond with this is:
url(r'^$', views.detail, name='detail')
Could I get help with correcting these two chunks of code?
In django, urls are matched by a regular expression pattern.
The general format of the url line is:
url(the_pattern, the_view_name_or_callable, **any_extra_arguments)
The key point is the_pattern, which is a regular expression and whatever is matched can be passed as an argument to the view function.
It is important that any parts of the pattern that are captured and passed on to the view function, actually match the function's signature (the def line, where you define the name and arguments). Otherwise, django will throw an error.
So now, with that out of the way - lets deal with the actual issue.
Your want a url like /the_great_gatsby to redirect to the page for The Great Gatsby.
The first step is to identify a pattern that matches the_great_gatsby. You can use [_\w]+ which means "one or more word characters or _", and plug it into the URL:
url(r'/[_\w]+$', views.detail, name='detail')
Next, you have to tell django how to capture that pattern and pass it to the view method as an argument.
Your view method is: def detail(request, movie_title). So django must pass whatever is after the / in the url (and matches the pattern) to the argument name movie_title, so what we want is this:
def detail(request, movie_title)
^^^^^^^^^^^
---------------|
|
vvvvvvv
url(r'/[_\w]+$', views.detail, name='detail')
We modify the regular expression to make sure that django captures whatever matches, and then assigns it a name. To do that, wrap the part of the regular expression in (?P<name_of_variable>expression) like this:
url(r'/(?P<movie_title>[_\w+])$', views.detail, name='detail')
Now, whatever is captured after / will be passed as the argument movie_title to the views.detail method.
Of course, you have to make sure your view function is doing the right thing with the captured string. In your case, your view method is searching by the primary key and will fail to produce any results (and will raise an exception) since there is no movie that will have the title as the primary key; but that's another problem.
you can configure your url and view like this
urls.py
url(r'^movie/(?P<movie_title>\w+)$', views.movie_detail, name='detail')
views.py
def movie_detail(request, movie_title):
movie_object = Movie.objects.get(pk=movie_title)
return render(request, 'moview-detail.html', {'movie_object':movie_object}
and in your html {% url 'app_name:detail' movie_title %}

How do I pass parameters via url in django?

I am trying to pass a parameter to my view, but I keep getting this error:
NoReverseMatch at /pay/how
Reverse for 'pay_summary' with arguments '(False,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['pay/summary/$']
/pay/how is the current view that I'm at. (that is the current template that that view is returning).
urls.py
url(r'^pay/summary/$', views.pay_summary, name='pay_summary')
views.py
def pay_summary(req, option):
if option:
#do something
else:
#do something else
....
template
my link
EDIT
I want the view should accept a POST request, not GET.
To add to the accepted answer, in Django 2.0 the url syntax has changed:
path('<int:key_id>/', views.myview, name='myname')
Or with regular expressions:
re_path(r'^(?P<key_id>[0-9])/$', views.myview, name='myname')
You need to define a variable on the url. For example:
url(r'^pay/summary/(?P<value>\d+)/$', views.pay_summary, name='pay_summary')),
In this case you would be able to call pay/summary/0
It could be a string true/false by replacing \d+ to \s+, but you would need to interpret the string, which is not the best.
You can then use:
my link

Redirect with HttpResponseRedirect to another function in python

I have a function :
def drawback(request,problem_id)
and I want in the end of this function to redirect to another page that is called from function
def show(request,problem_id)
I tried with
return HttpResponseRedirect(reverse('show',kwargs={'problem_id':10}))
return HttpResponseRedirect(reverse('show',kwargs={'problem_id':'10'}))
return HttpResponseRedirect(reverse('show',args=[10]))
return HttpResponseRedirect(reverse('show',args=(10))
Everything I found in other sites. But I receive the error
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'show' with arguments '()' and keyword arguments '{'problem_id': '10'}' not found.
or
Exception Value: Reverse for 'show' with arguments '(u'10',)' and keyword arguments '{}' not found.
This function and page works when I call it through html with a button. When I try to redirect from drawback function is not working.
urls.py
from django.conf.urls.defaults import *
from views import *
import settings
from django.conf import settings as rootsettings
urlpatterns = patterns('',
# authentication
(r'^start_auth', start_auth),
(r'^after_auth', after_auth),
# screens
(r'^problems/codelookup$', code_lookup),
# TESTING
(r'^problems/test$', test_message_send),
(r'^donnorsTool/$', problem_list),
(r'^problems/delete/(?P<problem_id>[^/]+)', archived_problem),
(r'^problems/edit/(?P<problem_id>[^/]+)', edit_problem),
(r'^problems/restore/(?P<problem_id>[^/]+)', restore_problem),
(r'^problems/new$', new_problem),
(r'^problems/archived$', archived_problems),
(r'^donnorsTool/show/(?P<problem_id>[^/]+)', show),
(r'^donnorsTool/consent/(?P<problem_id>[^/]+)/(?P<counter>[^/]+)', consent),
(r'^donnorsTool/withdraw/(?P<problem_id>[^/]+)/(?P<counter>[^/]+)', withdraw),
# static
## WARNING NOT FOR PRODUCTION
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': rootsettings.SERVER_ROOT_DIR + settings.STATIC_HOME}),
)
Just call it like a function :
def drawback(request,problem_id)
...
...
return show(request,10)
From the docs, you can do several things.
# using the Python path
reverse('news.views.archive')
# using the named URL
reverse('news_archive')
# passing a callable object
from news import views
reverse(views.archive)
I prefer names in case you want to change out the name of the view easily, so
in urls.py
(r'^donnorsTool/show/(?P<problem_id>[^/]+)', show, name='show'),
in views.py
return HttpResponseRedirect(reverse('show',kwargs={'problem_id':10}))
I found a solution. I am not sure if it is the best but for me it worked like:
return HttpResponseRedirect('../../show/'+problem_id)
I don't know if it will cause any problems like that.

Categories

Resources