How to redirect with variables in django?
Please guide me, thank you.
urls.py:
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^computer/$', views.computer, name='computer'),
url(r'^result/$', views.result, name='result'),
)
This is my original views.py :
def computer(request):
result = Computer.objects.order_by('?')[:1]
return render(request, 'many/result.html',{'result':result})
And I found I problem, render will not redirect to moneymany/result.html on the url,
so if the user refresh, it will get another result on the same page.
So I have to use redirect to many/result.html .
What's the usually way to redirect in django and I have to pass variable result?
I try this,but not work :
def result(request):
return render(request, 'many/result.html')
def computer(request):
result = Computer.objects.order_by('?')[:1]
url = reverse(('many:result'), kwargs={ 'result': result })
return HttpResponseRedirect(url)
you need
url(r'^result/(?P<result>[^\/]*)/$', views.result, name='result'),
and
return redirect(reverse('many:result', kwargs={ 'result': result }))
or (without changing url)
return redirect('/result/?p=%s' % result )
if you want to maintain POST data while redirecting, then it means your design isnot good. quoting Lukasz:
If you faced such problem there's slight chance that you had
over-complicated your design. This is a restriction of HTTP that POST
data cannot go with redirects.
How about using redirect.
from django.shortcuts import redirect
def computer(request):
result = Computer.objects.order_by('?')[:1]
return redirect('view-name-you-want', { 'result'=result })
this worked with i just needed to pass url parameters as arguments
return redirect('pagename' ,param1 , param2)
my url looks like :
path('page', views.somefunction, name="pagename")
Note: in my case somefunction accept only POST parameters
To redirect from a view to another view with data, you can use session with request.session['key'] and in this case, you don't need to modify path() in "myapp/urls.py" as shown below. Then, give the conbination of the app name "myapp", colon ":" and the view name "dest_view" which is set in path() in "myapp/urls.py" as shown below:
# "myapp/views.py"
from django.shortcuts import redirect
def redirect_view(request):
# Here
request.session['person'] = {'name': 'John', 'age': 27}
# Here
return redirect("myapp:dest_view")
# "myapp/urls.py"
from django.urls import path
from . import views
app_name = "myapp"
urlpatterns = [ # This is view name
path('dest/', views.destination_view, name="dest_view")
]
Then, this is how you get the data of "post" method:
# "myapp/index.html"
{{ request.session.person.name }} {# John #}
{{ request.session.person.age }} {# 27 #}
Related
I implemented some tests to check the status code of some pages, but this one with the reverse function throws me the error: django.urls.exceptions.NoReverseMatch: Reverse for 'ads.views.AdListView' not found. 'ads.views.AdListView' is not a valid view function or pattern name.
Reading the documentation and some answers on Stack Overflow I'm supposed to use either the view function name or the pattern name inside the parenthesis of the reverse function, but none of them seems to work.
Here's my code:
ads/tests/test_urls.py
from django.test import TestCase
from django.urls import reverse
class SimpleTests(TestCase):
def test_detail_view_url_by_name(self):
resp = self.client.get(reverse('ad_detail'))
# I've also tried: resp = self.client.get(reverse('ads/ad_detail'))
self.assertEqual(resp.status_code, 200)
...
ads\urls.py
from django.urls import path, reverse_lazy
from . import views
app_name='ads'
urlpatterns = [
path('', views.AdListView.as_view(), name='all'),
path('ad/<int:pk>', views.AdDetailView.as_view(), name='ad_detail'),
...
]
mysite/urls.py
from django.urls import path, include
urlpatterns = [
path('', include('home.urls')), # Change to ads.urls
path('ads/', include('ads.urls')),
...
]
ads/views.py
class AdDetailView(OwnerDetailView):
model = Ad
template_name = 'ads/ad_detail.html'
def get(self, request, pk) :
retrieved_ad = Ad.objects.get(id=pk)
comments = Comment.objects.filter(ad=retrieved_ad).order_by('-updated_at')
comment_form = CommentForm()
context = { 'ad' : retrieved_ad, 'comments': comments, 'comment_form': comment_form }
return render(request, self.template_name, context)
Any idea of what is causing the problem?
Since you use an app_name=… in your urls.py, you need to specify this as a namespace in the name of the view, so ads:ad_detail, and specify a primary key:
resp = self.client.get(reverse('ads:ad_detail', kwargs={'pk': 42}))
So here we visit the URL where 42 is used as value for the pk URL parameter.
This is a view written for my posts app in Django. The problem is that after filling the update form and submitting it happens successfully. But it creates confusion for the user because the same HTML page is there and how can I redirect into the updated object?
def post_update(request,id=None):
instance=get_object_or_404(Post,id=id)
if instance.created_user != request.user.username :
messages.success(request, "Post owned by another user, You are having read permission only")
return render(request,"my_blog/denied.html",{})
else :
form=PostForm(request.POST or None,request.FILES or None,instance=instance)
if form.is_valid():
instance=form.save(commit=False)
instance.save()
context={ "form":form,
"instance":instance }
return render(request,"my_blog/post_create.html",context)
As already suggested by #mdegis you can use the Django redirect function to redirect to another view or url.
from django.shortcuts import redirect
def view_to_redirect_to(request):
#This could be the view that handles the display of created objects"
....
perform action here
return render(request, template, context)
def my_view(request):
....
perform form action here
return redirect(view_to_redirect_to)
Read more about redirect here and here
You can pass positional or keyword argument(s) to the redirect shortcut using the reverse() method and the named url of the view you're redirecting to.
In urls.py
from news import views
url(r'^archive/$', views.archive, name='url_to_redirect_to')
In views.py
from django.urls import reverse
def my_view(request):
....
return redirect(reverse('url_to_redirect_to', kwargs={'args_1':value}))
More about reverse Here
You can use redirect from http shortcuts.
from django.shortcuts import redirect
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object) #or return redirect('/some/url/')
Here is the link to official docs.
To redirect from a view to another view, you need to give the conbination of the app name "myapp", colon ":" and the view name "dest_view" which is set in the path in "myapp/urls.py" as shown below. And, you don't need to modify the path in "myapp/urls.py" if you pass data with session with request.session['key'] as shown below:
# "myapp/views.py"
from django.shortcuts import render, redirect
def redirect_view(request):
# Here
request.session['person'] = {'name': 'John', 'age': 27}
# Here
return redirect("myapp:dest_view")
def destination_view(request):
return render(request, 'myapp/index.html', {})
You need to give the view name "dest_view" to path() in "myapp/urls.py" as shown below:
# "myapp/urls.py"
from django.urls import path
from . import views
app_name = "myapp"
urlpatterns = [ # This is view name
path('dest/', views.destination_view, name="dest_view")
]
Then, this is Django Template:
# "myapp/index.html"
{{ request.session.person.name }} {# John #}
{{ request.session.person.age }} {# 27 #}
from django.urls import reverse
def my_view(request):
....
return redirect(reverse('url_to_redirect_to', kwargs={'args_1':value(object.id for specific id)}))
I want to redirect and return view after submiting form on my homepage. Unfortunately after POST nothing is happend.
My homepage:
def home(request):
if request.method == 'POST':
url = request.POST['url']
bokeh(request,url)
return render(request,'home.html')
def bokeh(request,url):
//my calculation logic
return render(request,'bokeh.html')
Of course I send other attributes like dictionaries etc, but it works fine when I hardcode my url in browser. After clicking submit on my form in my homepage nothing is happend.
EDIT
my bokeh function look like that:
def bokeh(request,url):
source = urllib.request.urlopen(url).read()
soup = bs.BeautifulSoup(source, 'lxml')
descrp = [description.text for description in soup.find_all('p', class_="commit-title")]
author = [author.text for author in soup.find_all('a', class_="commit-author")]
dict1 = dict(zip(descrp,author))
dict2 = dict(Counter(dict1.values()))
label = list(dict2.keys())
value = list(dict2.values())
plot = figure(title='Github Effort',x_range=label,y_range=(0,30), plot_width=400, plot_height=400)
plot.line(label,value,line_width = 2)
script,div = components(plot)
return render(request,'bokeh.html',{'script': script,'div': div})
and my urls.py
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^bokeh/(?P<url>\w+)/$',views.bokeh,name='bokeh',url='url'),
]
And at this moment I got TypeError: url() got an unexpected keyword argument 'url'
You did not return the result of the bokeh function:
def home(request):
if request.method == 'POST':
url = request.POST['url']
return bokeh(request,url)
return render(request,'home.html')
Note however that this is not redirecting, and therefore you do not implement the Post/Redirect/Get pattern [wiki]. In case of a successful POST request, it is usually a good idea to perform a redirect, to prevent a user from refreshing the page, making the same POST request. A POST request frequently has side effects, and therefore we want to omit that.
You better make use of the redirect(..) function [Django-doc] here:
from django.shortcuts import redirect
def home(request):
if request.method == 'POST':
url = request.POST['url']
return redirect('bokeh', url=url)
return render(request,'home.html')
You should not use a url=… in the url(..) function:
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^bokeh/(?P<url>\w+)/$', views.bokeh, name='bokeh'),
]
My url.py is as below,
from myapp import views
urlpatterns = [
url(r'^myapp/get_requests/$', views.get_requests),
]
Now my views.py is as below,
#api_view(['GET'])
def get_request(request):
#How can I get request ID (base url here)?
return HttpResponse('test')
In the above if I do request in my browser with url as below it reaches my get_request method,
http://localhost:8080/myapp/get_requests/
But the same gives error 404 when I try with some ID in the end as below,
http://localhost:8080/myapp/get_requests/40
Now How can I get this ID number 40 in my views.py method?
Change your urls.py to
from myapp import views
urlpatterns = [
url(r'^myapp/get_requests/(?P<id>[0-9]+)$', views.get_requests),
]
Now get the id parameter in your views like this
#api_view(['GET'])
def get_request(request,id):
print id
return HttpResponse('test')
For more information check out django docs
If you want to pick up id from url, you just have to write something like this :
#login_required
def MyFunction(request, id) :
myobject = get_object_or_404(MyModel, pk=id)
context = {
"myobject" : myobject,
}
return render(request, 'my template.html', context)
And your url, you have to add url(r'^myapp/get_requests/(?P<id>\d+)/$', views.get_requests),
I assume your url is correct and he's already created with id inside. So I just gave you How I pick up object according to this ID.
There is a typo in the view function name in your above code. So, it would be get_requests not get_request.
Now coming to your question, it throws you 404 - Not Found because there is no actual route that you've defined that should expect the id after the url.
To start accepting id, add another route for it in your urls.py which has a digit regext like:
from myapp import views
urlpatterns = [
url(r'^myapp/get_requests/$', views.get_requests),
url(r'^myapp/get_requests/(?P<id>\d+)$', views.get_requests_with_id),
]
and in your views.py, define the view function to accept id parameter something like this:
#api_view(['GET'])
def get_requests_with_id(request, id):
# Now use id for whatever you want
return HttpResponse('test')
You can read about it form the official documentation here: https://docs.djangoproject.com/en/1.11/topics/http/urls/#named-groups
AoA,
I am trying to redirect to some view, but failed to do so.
here is the code
views.py
def logout(request):
c = {'username': 'Create Account', 'status': ''}
c.update(csrf(request))
response = render_to_response("home.html",c)
response.delete_cookie('id')
request.session['id'] = 'None'
return redirect('/home/')
def home(request):
#some code here
return render_to_response('blah blah')
urls.py
url(r'^home/$', 'contacts.views.home_Page'),
url(r'^logout/$', 'contacts.views.logout'),
the above code redirect me to -- let's suppose current URL(127.0.0.1/account)
it redirects me to (127.0.0.1/account/home) but i want to redirect to 127.0.0.1/home
how can I redirect to specific view ?
redirect(to[, permanent=False], *args, **kwargs) returns an HttpResponseRedirect to the appropriate URL for the arguments passed. You need to return the HttpResponseRedirect object in the view function.
BTW, you should try to avoid hardcoding urls in you code, instead you should use view names.
e.g:
urls.py:
url(r'^home/$', home, name='home_view')
...
view.py:
def logout(request):
...
redirect('home_view')
django provides a built-in logout that you should use:
from django.shortcuts import redirect
from django.contrib.auth import logout
def log_out(request):
logout(request)
return redirect('home')
Now 'home' can be many things; but the easiest way to make sure its pointing to the right place is to name your urls. So in your urls.py:
url(r'home/$', home, name='home')