passing GET parameter from python view to template - python

As simple as this is, I'm having trouble getting the value of a GET parameter d
I'm clicking on a link like:
http://127.0.0.1:8000/Account/Site/d=mysite.com
The view that, that url serves is:
#login_required
def Site(request):
if request.user.is_authenticated():
# verify domain in url is associated with authenticated users account
DomainToScan = request.GET.get('d')
VerifyDomainAgainstDb = Tld.objects.filter(FKtoClient=request.user,domainNm=DomainToScan)
else:
HttpResponseRedirect("/Login/")
return render(request, 'VA/account/begin_site.html', {
'Site':Site,
'VerifyDomainAgainstDb':VerifyDomainAgainstDb
})
specifically, this line:
DomainToScan = request.GET.get('d')
the value of DomainToScan is outputting as None when viewing the django template begin_site.html
What am I doing wrong here?
Thank you!
UPDATE:
urls.py
(r'^Account/Site/[?]d=[A-za-z0-9]{2,50}.[a-z]{1,3}$', Site),
For some reason this isn't matching a url like:
http://127.0.0.1:8000/Account/Site/?d=mysite.com
Any reason why? Rubular says its valid

You don't have any GET parameters. If you want domain to be a GET parameter, your link should be http://127.0.0.1:8000/Account/Site/?d=mysite.com - notice the ?.
(Also note you would need to actually return HttpResponseRedirect(), not just call it: but the whole checking of is_authenticated is pointless anyway because the function is decorated with login_required, so a non-authenticated user wouldn't even get into that view.)

Try:
#login_required
def Site(request, DomainToScan=None):
if request.user.is_authenticated():
# verify domain in url is associated with authenticated users account
VerifyDomainAgainstDb = Tld.objects.filter(FKtoClient=request.user,domainNm=DomainToScan)
else:
return HttpResponseRedirect("/Login/")
return render(request, 'VA/account/begin_site.html', locals())
urls.py
(r'^Account/Site/(?P<DomainToScan>[^/]+)/', Site),

Related

django - how can I add more to my URL in my views.py?

I have a url, http://127.0.0.1:8000/lesson/riff-lab/1305/pentab-wow/
When a user navigates to the above url, I want to change it to http://127.0.0.1:8000/lesson/riff-lab/1305/pentab-wow/?d:a3ugm6eyko59qhr/pentab-Track_1.js
The appended part is needed in order to load something that I want to load, but the specifics are not important for this question.
Here's what I have tried.
def my_view(request, pk):
context = {}
page = Page.objects.get(pk=pk)
request.GET._mutable = True
request.GET['?d:%s/%s' % (page.dropbox_key, page.dropbox_js_file_name)] = ""
return render(request, template, context)
Also
def my_view(request, pk):
context = {}
page = Page.objects.get(pk=pk)
request.GET = request.GET.copy()
request.GET['?d:%s/%s' % (page.dropbox_key, page.dropbox_js_file_name)] = ""
return render(request, template, context)
These do not change the url.
Can anyone help? Thanks in advance.
You trying to change the aim of a shell that already has hit it's target.
URL comes first, then view routed to it is processed, there is no way to change it without making another request, e.g. returning a redirect response "please open this url now" to the client.
You can easily find it in django docs by this keywords, but what you are trying to do generally doesn't look very reasonable, if you know beforehand how you need to construct url, why change it mid-way or why change it at all if view has all required data? I don't know your context, but it's probable that you need to reconsider your approach.

django object has no id, or is at least not passing any id [duplicate]

In my view function I want to call another view and pass data to it :
return redirect('some-view-name', backend, form.cleaned_data)
, where backend is of registration.backends object, and form.cleaned_data is a dict of form data (but both must be either sent as *args or **kwargs to prevent raising Don't mix *args and **kwargs in call to reverse()! error). From what I've found in the docs :
def my_view(request):
...
return redirect('some-view-name', foo='bar')
It looks like I need to provide 'some-view-name' argument, but is it just the name of the view function, or the name of the url ? So I would like to make it similar to the way it's done in django-registration, where :
to, args, kwargs = backend.post_registration_redirect(request, new_user)
return redirect(to, *args, **kwargs)
def post_registration_redirect(self, request, user):
return ('registration_complete', (), {})
Ok so now, can I call directly my view function or do I need to provide a url for it ? And what more important, how my funciotn call (and a url if needed) should look like ? Both backend, and cleaned_data are just passed through this view for a later usage. I've tried this, but it's improper :
url(r'^link/$', some-view-name)
def some-view-name(request, *args):
As well as this :
return redirect('some_url', backend=backend, dataform.cleaned_data)
url(r'^link/$', some-view-name)
def some-view-name(request, backend, data):
still NoReverseMatch . But in django-registration, I've seen something like this :
url(r'^register/$',register,{'backend': 'registration.backends.default.DefaultBackend'}, name='registration_register'),
def register(request, backend, success_url=None, form_class=None,
disallowed_url='registration_disallowed',
template_name='user/login_logout_register/registration_form.html',
extra_context=None):
urls.py:
#...
url(r'element/update/(?P<pk>\d+)/$', 'element.views.element_update', name='element_update'),
views.py:
from django.shortcuts import redirect
from .models import Element
def element_info(request):
# ...
element = Element.object.get(pk=1)
return redirect('element_update', pk=element.id)
def element_update(request, pk)
# ...
Firstly, your URL definition does not accept any parameters at all. If you want parameters to be passed from the URL into the view, you need to define them in the urlconf.
Secondly, it's not at all clear what you are expecting to happen to the cleaned_data dictionary. Don't forget you can't redirect to a POST - this is a limitation of HTTP, not Django - so your cleaned_data either needs to be a URL parameter (horrible) or, slightly better, a series of GET parameters - so the URL would be in the form:
/link/mybackend/?field1=value1&field2=value2&field3=value3
and so on. In this case, field1, field2 and field3 are not included in the URLconf definition - they are available in the view via request.GET.
So your urlconf would be:
url(r'^link/(?P<backend>\w+?)/$', my_function)
and the view would look like:
def my_function(request, backend):
data = request.GET
and the reverse would be (after importing urllib):
return "%s?%s" % (redirect('my_function', args=(backend,)),
urllib.urlencode(form.cleaned_data))
Edited after comment
The whole point of using redirect and reverse, as you have been doing, is that you go to the URL - it returns an Http code that causes the browser to redirect to the new URL, and call that.
If you simply want to call the view from within your code, just do it directly - no need to use reverse at all.
That said, if all you want to do is store the data, then just put it in the session:
request.session['temp_data'] = form.cleaned_data
I do like this in django3
redirect_url = reverse('my_function', args=(backend,))
parameters = urlencode(form.cleaned_data)
return redirect(f'{redirect_url}?{parameters}')
I am new to Django. One of my project, I used render instead of redirect to send data. That worked good. My code was like this --->
for key, value in request.POST.lists():
print(key, value)
if key.split('-')[-1] != 'csrfmiddlewaretoken':
qu_id = key.split('-')[-1]
get_answer = Answer.objects.filter(question_id=qu_id,
correct_answer__option__contains=value[0])
total_correct_answer = get_answer.count()
context = {'score': total_correct_answer}
return render(request, 'result.html', context)
context = {'questions': questions, 'total_correct_answer': total_correct_answer}
return render(request, 'test.html', context)

render_to_response or redirect changes the template elements in Django 1.8

I'm trying to check if email id entered by user is existing in the database table, if existing - I would like to route to 'prof.html' template otherwise just show a message in the login.html template.
Both the conditions are working fine.
However, the problem is when I use redirect() or render_to_response() -
the destination template elements like div, input etc., are being changed automatically (prof.html in this case) ?
Can we also send the context information to destination template ?
(response data or any object from the database and redirect to prof.html template via view in this case)
Below is my code :
Views.py
def verifyme(request):
if request.method == "POST":
emailid4loginV = request.POST['emailid4login_Aj']
else:
emailid4loginV = ''
response_data = ''
return HttpResponse(response_data, content_type="text/plain")
response_data = ''
if Employee.objects.filter(email = emailid4loginV).exists():
response_data='Thanks for waiting - login successful'
#return render_to_response('app/prof.html', { 'response_data':response_data},
# context_instance = RequestContext( request ) )
return redirect('/myprofile')
else:
response_data='Ouch! you are not a registered user!'
return HttpResponse(response_data, content_type="text/plain")
urls.py
url(r'^myprofile$', 'app.views.profile', name='profile'),
Just for your info, 'profile' view does return some objects from the table and renders in the template app/prof.html.
I observed that the destination template is being rendered in same login.html template (How ? : In the browser url, I dont see myprofile - but the one for login) But when I request the myprofile manually by entering in the website url (localhost:xxxxx/myprofile), it works perfectly :(
URL before submitting request in login.html :
URL after submitting request in login.html - myprofile is rendered in the same page :
When I manually type in the url, template just works perfectly..
Could you please let me know what could be the problem ?
EDIT:
Solved this issue with a little trick, posted in the below
https://stackoverflow.com/questions/31091938/why-is-httpresponseredirectreverse-doesnt-redirect-to-new-page
1) Actually there are many ways to pass data to next view ... generally in such cases like you have better way - using sessions (cookie|localstorage|sessionstorage), it is like clipboard ... save session data in one view and get it later in another one. For example:
First view:
self.request.session['response_data'] = 'some text'
self.request.session.set_expiry(0) # user’s session cookie will expire when the user’s Web browser is closed.
Other views:
response_data = self.request.session.get('response_data', '')
But if you planning just use this data in template Django has some kind more high-level interface for it and in your case semantically right to use it - The messages framework https://docs.djangoproject.com/en/1.8/ref/contrib/messages/
2) If you want redirect to another view better use url namespaces and reverse https://docs.djangoproject.com/en/1.8/ref/urlresolvers/#reverse
return HttpResponseRedirect(reverse(app.views.profile)) # here I've passed callable object because you have not show your app url namespace, but generally use namespaces
https://docs.djangoproject.com/en/1.8/topics/http/urls/#url-namespaces

POST in django. How does a user update?

I'm brand new to django and fairly new to programming in general. I've done the django tutorial and searched the web for an answer to this question, but to no avail, so now I'm here. I am confused how post works with django. All of the tutorials I've looked at how have a return function in views that displays the webpage. I get that. But then how does a user update data if the page is being rendered from that return statement? After the return there can't be any more updates because the function stops, right? What am I missing here? Any help would be greatly appreciated, I'm getting fairly desperate here.
One pattern for Django views (by no means the only pattern) is to check the request method (GET or POST) at the beginning of the view. If it is POST, then handle the incoming data (before the view returns), and then return either a rendered template, or a redirect.
def view_function(request):
if request.method == 'POST':
if data_is_valid(request.POST):
save_data(request.POST)
return HttpResponseRedirect('/somewhere/good')
else:
return render('template', {'errors': what_went_wrong}
else:
return render('template')
The user updates data in the logic of the view function. That is to say, if the user wishes to update something, you place the update logic in the view function before the return. For example, you would do this:
def update(request):
item = <some model>.objects.get(<something>)
<more code>
return <something>
Usually an edit view function contains two parts -- one for updating data, and the other for displaying the update form. For example,
def user_edit(request):
if request.method == 'POST': # is this a save action?
# save the user data
user_id = request.POST.get('user_id')
username = request.POST.get('username')
description = request.POST.get('description')
user = User.objects.get(id=user_id)
user.username = username
user.description = description
user.save()
return HttpResponseRedirect('/user/') # redirect to index
else:
# show the edit form
user_id = request.GET.get('user_id')
user = User.object.get(id=user_id)
return render_to_response('/user/edit.html', { 'user': user })
There are many different choices for the if request.method == 'POST' line. You can also use if request.POST.get('user_id') to check if specified field is set, to determine if this is a save action.

Django return redirect() with parameters

In my view function I want to call another view and pass data to it :
return redirect('some-view-name', backend, form.cleaned_data)
, where backend is of registration.backends object, and form.cleaned_data is a dict of form data (but both must be either sent as *args or **kwargs to prevent raising Don't mix *args and **kwargs in call to reverse()! error). From what I've found in the docs :
def my_view(request):
...
return redirect('some-view-name', foo='bar')
It looks like I need to provide 'some-view-name' argument, but is it just the name of the view function, or the name of the url ? So I would like to make it similar to the way it's done in django-registration, where :
to, args, kwargs = backend.post_registration_redirect(request, new_user)
return redirect(to, *args, **kwargs)
def post_registration_redirect(self, request, user):
return ('registration_complete', (), {})
Ok so now, can I call directly my view function or do I need to provide a url for it ? And what more important, how my funciotn call (and a url if needed) should look like ? Both backend, and cleaned_data are just passed through this view for a later usage. I've tried this, but it's improper :
url(r'^link/$', some-view-name)
def some-view-name(request, *args):
As well as this :
return redirect('some_url', backend=backend, dataform.cleaned_data)
url(r'^link/$', some-view-name)
def some-view-name(request, backend, data):
still NoReverseMatch . But in django-registration, I've seen something like this :
url(r'^register/$',register,{'backend': 'registration.backends.default.DefaultBackend'}, name='registration_register'),
def register(request, backend, success_url=None, form_class=None,
disallowed_url='registration_disallowed',
template_name='user/login_logout_register/registration_form.html',
extra_context=None):
urls.py:
#...
url(r'element/update/(?P<pk>\d+)/$', 'element.views.element_update', name='element_update'),
views.py:
from django.shortcuts import redirect
from .models import Element
def element_info(request):
# ...
element = Element.object.get(pk=1)
return redirect('element_update', pk=element.id)
def element_update(request, pk)
# ...
Firstly, your URL definition does not accept any parameters at all. If you want parameters to be passed from the URL into the view, you need to define them in the urlconf.
Secondly, it's not at all clear what you are expecting to happen to the cleaned_data dictionary. Don't forget you can't redirect to a POST - this is a limitation of HTTP, not Django - so your cleaned_data either needs to be a URL parameter (horrible) or, slightly better, a series of GET parameters - so the URL would be in the form:
/link/mybackend/?field1=value1&field2=value2&field3=value3
and so on. In this case, field1, field2 and field3 are not included in the URLconf definition - they are available in the view via request.GET.
So your urlconf would be:
url(r'^link/(?P<backend>\w+?)/$', my_function)
and the view would look like:
def my_function(request, backend):
data = request.GET
and the reverse would be (after importing urllib):
return "%s?%s" % (redirect('my_function', args=(backend,)),
urllib.urlencode(form.cleaned_data))
Edited after comment
The whole point of using redirect and reverse, as you have been doing, is that you go to the URL - it returns an Http code that causes the browser to redirect to the new URL, and call that.
If you simply want to call the view from within your code, just do it directly - no need to use reverse at all.
That said, if all you want to do is store the data, then just put it in the session:
request.session['temp_data'] = form.cleaned_data
I do like this in django3
redirect_url = reverse('my_function', args=(backend,))
parameters = urlencode(form.cleaned_data)
return redirect(f'{redirect_url}?{parameters}')
I am new to Django. One of my project, I used render instead of redirect to send data. That worked good. My code was like this --->
for key, value in request.POST.lists():
print(key, value)
if key.split('-')[-1] != 'csrfmiddlewaretoken':
qu_id = key.split('-')[-1]
get_answer = Answer.objects.filter(question_id=qu_id,
correct_answer__option__contains=value[0])
total_correct_answer = get_answer.count()
context = {'score': total_correct_answer}
return render(request, 'result.html', context)
context = {'questions': questions, 'total_correct_answer': total_correct_answer}
return render(request, 'test.html', context)

Categories

Resources