Post to django view from another view - python

Facing some constraints in a website, I was obligated to try to post data to some view from another view (I suppose it does make sense), like:
def view1(request):
if request.method == 'POST':
value = request.POST.get('h1')
''' '''
And in my view2, I would do something like:
def view2(request):
if constraint:
python.post(/url/view1/,data={'h1':1}) # Doesn't exist
# Just a demonstration
Is there a way to do what I want?

you could use the requests package to send request to other URLs, the question is "why" ??.
Why not extract the code of view1 in a utility function and call int from view2?
If you need to use an new HTTP request, I suggest to use the Django reverse() function to the the URL from the urls.py configuration (refer to the official documentation )

Use the requests library to do this.

Take a look at Python Requests: I found it in in Python forum to print which could be modified to post.
import requests
req = requests.Request('POST','http://stackoverflow.com',headers={'X-Custom':'Test'},data='a=1&b=2')
prepared = req.prepare()
def pretty_print_POST(req):
"""
At this point it is completely built and ready
to be fired; it is "prepared".
However pay attention at the formatting used in
this function because it is programmed to be pretty
printed and may differ from the actual request.
"""
print('{}\n{}\n{}\n\n{}'.format(
'-----------START-----------',
req.method + ' ' + req.url,
'\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
req.body,
))
pretty_print_POST(prepared)

Related

Django 2+ : Optional URL using PATH, without making multiple URL

i have this url
path('<slug>/thank_you/<user_id>', thank_you, name='thank_you'),
i want the <user_id> to be optional, but i dont want to make 2 urls like this
path('<slug>/thank_you', thank_you, name='thank_you'),
path('<slug>/thank_you/<user_id>', thank_you, name='thank_you2'),
i understand that you can make it optional using regex, but thats if you're using django <2 (using url, not path)
how do i obtain this ?
You can use URL Query String for this. For example:
# URL
path('/thank_you/', thank_you, name='thank_you'),
# View
def thank_you(request, slug):
user_id = request.GET.get('from')
# rest of the code
# Example route
http://localhost:8000/dummy-slug/thank_you/?from=dummy_user_id

Wagtail render any path in index page

I need to enable some pages to write an arbitrary URL that does not depend on the structure of the site.
For example I have structure:
/
/blog
/blog/blogpost1
/blog/blogpost2
But, for example, I need change url from /blog/blbogpost2 to /some/blogpost/url1
For this, I decided to give the opportunity to handle any URL of the main page of the site.
class IndexPage(RoutablePageMixin, Page):
...
#route(r'^(?P<path>.*)/$')
def render_page_with_special_path(self, request, path, *args, **kwargs):
pages = Page.objects.not_exact_type(IndexPage).specific()
for page in pages:
if hasattr(page, 'full_path'):
if page.full_path == path:
return page.serve(request)
# some logic
But now, if this path is not found, but I need to return this request to the standard handler. How can I do it?
This isn't possible with RoutablePageMixin; Wagtail treats URL routing and page serving as two distinct steps, and once it's identified the function responsible for serving the page (which, for RoutablePageMixin, is done by checking the URL route given in #route), there's no way to go back to the URL routing step.
However, it can be done by overriding the page's route() method, which is the low-level mechanism used by RoutablePageMixin. Your version would look something like this:
from wagtail.core.url_routing import RouteResult
class IndexPage(Page):
def route(self, request, path_components):
# reconstruct the original URL path from the list of path components
path = '/'
if path_components:
path += '/'.join(path_components) + '/'
pages = Page.objects.not_exact_type(IndexPage).specific()
for page in pages:
if hasattr(page, 'full_path'):
if page.full_path == path:
return RouteResult(page)
# no match found, so revert to the default routing mechanism
return super().route(request, path_components)

Executing Javascript on a webpage with python requests

I am not sure if this is possible but let me try to explain.
I am trying to post data from a form but before my data gets posted the website encrypts some of it, with a public key, that i am able to achieve from the response.text
I found the javascript that is used
var myVal = 123
n = (myVal, ClassName.create(publicKey);
n.encrypt(myVal)
The .encrypt returns the string that is passed to the form. My question is can I somehow bring that javascript into my script so I can execute that .encrypt method to pass that properly to the form?
if the script is simple,I will use pyexecjs
import execjs
js_cmd = '''
function add(x,y){
return x+y
}
'''
cxt = execjs.compile(js_cmd)
print(cxt.eval("add(3,4)"))

Assigning URL String to Variable in Django

From what I can see there are 2 ways of using a string from within the URL. Either by using the URLConf or via request.GET.get.
Im trying to use the request.GET.get method and trying to capture the string after the = sign on a URL such as www.domain.co.uk/macoui=001100
URLConf
url(r'^macoui=\d{6}$', 'domain.views.output'),
View
def output(request):
if request.method == 'GET':
request.GET.get('macoui', '')
return render_to_response('template.html', {'response': '\'%s\' % (macoui)}, context_instance=RequestContext(request))
When I run this I get an error saying "nothing to repeat".
Thanks,
You have quite a few errors here.
You've correctly stated that there are two ways of getting parameters, then confused them both. If you're matching things in the urlconf, then you don't use request.GET to get them. Anyway, request.GET is only for querystring parameters - that is, URLs of the form www.domain.co.uk/?param=value where the ? is the necessary part.
If your URL is really www.domain.co.uk/macoui=001100 - without the ? - then you need to fix your regular expression as follows:
url(r'^macoui=(?P<macaoui>\d{6})$', 'domain.views.output'),
and your view as follows:
def output(request, macaoui):
However, if - as is much more likely - your URL is www.domain.co.uk/?macoui=001100 - with a question mark - then your URLconf should just be:
url(r'^$', 'domain.views.output'),
and your view becomes:
def output(request):
macaoui = request.GET.get('macoui', '')
I believe you have a problem in this line:
{'response': '\'%s\' % (macoui)}
As you're escaping the last apostrophe and the entire string is never closed. You'll be better off using the other string delimiters:
{'response': "'%s'" % (macoui)}
Good luck.
You should simply do.
url(r'^/.*', 'domain.views.output'),
then use URL, www.domain.co.uk/?macoui=001100
URL on your example what not proper as get parameters (request.GET) on request uri are followed after '?'

pycurl script can't login to website

I'm currently trying to get a grasp on pycurl. I'm attempting to login to a website. After logging into the site it should redirect to the main page. However when trying this script it just gets returned to the login page. What might I be doing wrong?
import pycurl
import urllib
import StringIO
pf = {'username' : 'user', 'password' : 'pass' }
fields = urllib.urlencode(pf)
pageContents = StringIO.StringIO()
p = pycurl.Curl()
p.setopt(pycurl.FOLLOWLOCATION, 1)
p.setopt(pycurl.COOKIEFILE, './cookie_test.txt')
p.setopt(pycurl.COOKIEJAR, './cookie_test.txt')
p.setopt(pycurl.POST, 1)
p.setopt(pycurl.POSTFIELDS, fields)
p.setopt(pycurl.WRITEFUNCTION, pageContents.write)
p.setopt(pycurl.URL, 'http://localhost')
p.perform()
pageContents.seek(0)
print pageContents.readlines()
EDIT: As pointed out by Peter the URL should point to a login URL but the site I'm trying to get this to work for fails to show me what URL this would be. The form's action just points to the home page ( /index.html )
As you're troubleshooting this problem, I suggest getting a browser plugin like FireBug or LiveHTTPHeaders (I suggest Firefox plugins, but there are similar plugins for other browsers as well). Then you can exercise a request to the site and see what action (URL), method, and form parameters are being passed to the target server. This will likely help elucidate the crux of the problem.
If that's no help, you may consider using a different tool for your mechanization. I've used ClientForm and BeautifulSoup to perform similar operations. Based on what I've read in the pycURL docs and your code above, ClientForm might be a better tool to use. ClientForm will parse your HTML page, locate the forms on it (including login forms), and construct the appropriate request for you based on the answers you supply to the form. You could even use ClientForm with pycURL... but at least ClientForm will provide you with the appropriate action to which to POST, and construct all of the appropriate parameters.
Be aware, though, that if there is JavaScript handling any necessary part of the login form, even ClientForm can't help you there. You will need something that interprets the JavaScript to effectively automate the login. In that case, I've used SeleniumRC to control a browser (and I let the browser handle the JavaScript).
One of the golden rule, you need to 'brake the ice', have debugging enabled when trying to solve pycurl example:
Note: don't forget to use p.close() after p.perform()
def test(debug_type, debug_msg):
if len(debug_msg) < 300:
print "debug(%d): %s" % (debug_type, debug_msg.strip())
p.setopt(pycurl.VERBOSE, True)
p.setopt(pycurl.DEBUGFUNCTION, test)
Now you can see how your code is breathing, because you have debugging enabled
import pycurl
import urllib
import StringIO
def test(debug_type, debug_msg):
if len(debug_msg) < 300:
print "debug(%d): %s" % (debug_type, debug_msg.strip())
pf = {'username' : 'user', 'password' : 'pass' }
fields = urllib.urlencode(pf)
pageContents = StringIO.StringIO()
p = pycurl.Curl()
p.setopt(pycurl.FOLLOWLOCATION, 1)
p.setopt(pycurl.COOKIEFILE, './cookie_test.txt')
p.setopt(pycurl.COOKIEJAR, './cookie_test.txt')
p.setopt(pycurl.POST, 1)
p.setopt(pycurl.POSTFIELDS, fields)
p.setopt(pycurl.WRITEFUNCTION, pageContents.write)
p.setopt(pycurl.VERBOSE, True)
p.setopt(pycurl.DEBUGFUNCTION, test)
p.setopt(pycurl.URL, 'http://localhost')
p.perform()
p.close() # This is mandatory.
pageContents.seek(0)
print pageContents.readlines()

Categories

Resources