Django: how to download file from a given url from user? - python

I am trying to let user provide a url and django will download automatically but have no idea what to do. Thanks in advance.

My advice is you use celery and request to asynchroniusly download the files. There's a site that explains thoroughly how to integrate Django and Celery

You can retrieve a url using the requests library.
To get the URL from the user, you can use a form.
Then, in the view, you can do something like
if request.method == 'POST': # If the form has been submitted...
form = URLForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
response = requests.get(form.entered_url,stream=True)
with open('save_file','w') as f:
for chunk in response.iter_content():
f.write(chunk)
return HttpResponseRedirect('/thanks/') # Redirect after POST

Related

How can I return a redirect and file in Django?

I'm working on a form that when submitted has the option to export a PDF. This is great, but I would also like to be able to return a new URL for the user to be redirected to as well as downloading the file. Something that combines render() or redirect() with FileResponse().
For this to work, you will need two views. One to serve the redirect and another one to serve the file to be downloaded. Here is a simplified implementation:
def myform(request):
form = MyForm(request.POST)
if form.is_valid():
return redirect("/download/file.pdf")
def download(request):
file = open("file.pdf", "rb")
return FileResponse(file, as_attachment=True)

django redirecting back to the page from where the request was made

I implemented in django return to original page via redirect see view example
#login_required
def category_edit(request, pk,uri):
post = get_object_or_404(Category, pk=pk)
if request.method == "POST":
form = CategoryForm(request.POST, instance=post)
if form.is_valid():
category = form.save(commit=False)
category.author = request.user
category.creation_time = timezone.now()
category.save()
return redirect(uri)
#return redirect('category_details', pk=post.id)
else:
form = CategoryForm(instance=post)
return render(request, 'item/category_edit.html', {'form': form})
So basically after each operation like edit,new I redirect back to from where the call was originally made. (I stoped using it in case of delete since in case of delete the page might not exist any more)
However in one of my questons somebody mentioned that it is better approach to add a path to URL instead of sending URL as parameter to add it in the link
Delete
From samples and documentation I figured out this approach should automatically work in django if I have in my settings in 'context_processors' included 'django.template.context_processors.request'. (However the samples I saw where dated to previous versions of Django)
But this approach didn't work. So my question is does ?next={{request.path}} is still supported in Django 1.8 and if yes what step I am missing.
Any feedback on what approach is better the redirect or the ?next={{request.path}} is welcome as well.

How do I make a POST request to flask?

I'm new to Flask and I'm trying to find a way to invoke the elif statement in the code below, without having to manually type in the url when I run my app. In other words, I'd like to be able to provide a url in one of my templates that will make a POST request for question(title). Can anyone give me insight?
#application.route('/question/<title>', methods=['GET', 'POST'])
def question(title):
if request.method == 'GET':
question = r.get(title+':question')
return render_template('AnswerQuestion.html',
question = question)
elif request.method == 'POST':
submittedAnswer = request.form['submittedAnswer'];
answer=r.get(title+':answer')
if submittedAnswer == answer:
return render_template('Correct.html');
else:
return render_template('Incorrect.html',
answer = answer,
submittedAnswer = submittedAnswer);
Looks like in thePOST request, you are getting the contents of a form. You can try to create a form whose action="/question/some_title" and method="post". So on submit this will be handled on theelif part of your flask code.
Or you can try sending am ajax request through JavaScript or jQuery, with relevant data, method and URL.

Django form submit again on refresh

Hello I am working on a simple form. The form submits fine but if I refresh the page it resubmits the data. Seems the form is holding the data after submit and I assume since after the submit the request method is post. Question is what is the best way after the submit to clear the form in Django. After the submit the form variables should not be holding the values anymore. Thanks
def testimonials(request, template_name="testimonials.html"):
reviews = Reviews.objects.all()
if request.method == 'POST':
form = forms.ReviewsForm(data = request.POST)
# create a new item
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
if form.is_valid():
nameIn = form.cleaned_data['name']
reviewIn = form.cleaned_data['review']
newReview = Reviews(name = nameIn, review = reviewIn)
newReview.save()
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
else:
# This the the first page load, display a blank form
form = forms.ReviewsForm()
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
Typically, you would issue a redirect after processing a form/POST request (this is common web development practice to avoid the resubmission issue you mentioned). So instead of a render_to_response, you might issue a HttpResponseRedirect like so:
if form.is_valid():
# Process form as desired here
# Simple example; use reverse() to avoid hard-coding URLs
return HttpResponseRedirect('/success/')
Check out the using a form in view for a skeleton of how forms are typically processed.
use reverse instead of render to response
if form.is_valid():
nameIn = form.cleaned_data['name']
reviewIn = form.cleaned_data['review']
newReview = Reviews(name = nameIn, review = reviewIn)
newReview.save()
return HttpResponseRedirect(reverse('app_name:url'))
You could also use the 'redirect' shortcut:
from django.shortcuts import redirect
...
return redirect(newReview)
This is assuming you have get_absolute_url defined in your Review Model.
See the docs for more info.

How can I redirect after POST in Pyramid?

I'm trying to have my form submit to a route which will validate the data then redirect back to the original route.
For example:
User loads the page website.com/post
Form POSTs the data to website.com/post-save
User gets redirected back to website.com/post
Pyramid is giving me some troubles doing this.
Here's my slimmed down views.py
def _get_link_form(post_data):
""" Returns the initialised form object """
return LinkForm(post_data)
def home_page(request):
form = _get_link_form(request.POST)
return {'form' : form}
def save_post(request):
""" form data is submitted here """"
form = _get_link_form(request.POST)
if not form.validate():
return home_page(request, form)
This is the code I've been playing around with. Not only does it not work, it also feels messy and hacked up. Surely there's a simpler way to 'redirect after-POST' in Pyramid?
Your problem is most easily solved by simply POSTing to the same URL that your form is shown at, and simply redirecting the user away from the page when the POST is successful. That way until the form is successfully submitted you do not change URLs.
If you're just dying to POST to a different URL, then you need to save the data using sessions, since you're obviously handling the form data between requests.
Typically if you want to be able to handle errors in your forms you would use a session and flash messages. To do this you simply add a location for flash messages to appear in your base template and setup session support using something like pyramid_beaker.
Assuming your home page is setup at the 'home' named-route:
from pyramid.httpexceptions import HTTPFound
def myview(request):
user = '<default user field value>'
if 'submit' in request.POST:
user = request.POST.get('user')
# validate your form data
if <form validates successfully>:
request.session.flash('Form was submitted successfully.')
url = request.route_url('home')
return HTTPFound(location=url)
return {
# globals for rendering your form
'user': user,
}
Notice how if the form fails to validate you use the same code you did to render the form originally, and only if it is successful do you redirect. This format can also handle populating the form with the values used in the submission, and default values.
You can loop through the flash messages in your template of choice using request.session.peek_flash() and request.session.pop_flash().
route_url supports mutating the query string on the generated url as well, if you want to flag your home page view to check the session data.
You can obviously just pass everything in the query string back to the home page, but that's a pretty big security vulnerability that sessions can help protect against.
The Pyramid documentation has a particularly on-point section with the following example:
from pyramid.httpexceptions import HTTPFound
def myview(request):
return HTTPFound(location='http://example.com')
I do this like so:
from pyramid.httpexceptions import HTTPCreated
response = HTTPCreated()
response.location = self.request.resource_url( newResource )
return response
This sends the HTTP Created code , 201
The Pyramid documentation has content about Redirect, you can see more information in below link :
Pyramid documentation
import pyramid.httpexceptions as exc
raise exc.HTTPFound(request.route_url("section1")) # Redirect
Edited:
Actually you can do that on client side with Javascript, first you should send particular response to client side(either with flashes some data or return Response object):
window.location = '{{ request.route_path("route_name") }}';
Assuming your homepage is the default view of your pyramid web app, you can do:
def _get_link_form(post_data):
""" Returns the initialised form object """
return LinkForm(post_data)
def home_page(request):
form = _get_link_form(request.POST)
return {'form' : form}
def save_post(request):
form = _get_link_form(request.POST)
if not form.validate():
from pyramid.httpexceptions import HTTPFound
return HTTPFound(location=request.application_url)
Basically you need to know how the home_page view was "added" to your Configurator. If your homepage actually lives at /few/levels/deep/homepage then a redirect might look like this:
return HTTPFound(location=request.application_url + '/few/levels/deep/homepage')
A clean way is using the "overload" provided by pyramid for different request types, por example, you can decorate your methods this way:
#action(request_method='GET',
renderer='mypackage:/templates/save.mako',
name='save')
def save(request):
''' Fill the template with default values or leave it blank'''
return {}
#action(request_method='POST',
renderer='mypackage:/templates/save.mako',
name='save')
def save_post(request):
""" form data is submitted here """"
# process form
In the HTML, you must call the action form, like
<form method="POST" id="tform" action="${request.route_url('home', action='save')}">
This way, one method is processed when the method POST is used, and the other when the GET is used. The same name, but two implementations.

Categories

Resources