How to use uploaded file info to fill in form fields - django

I am trying to create a file upload form where a user uploads a file and then I do some processing on it. After processing the file, I want to redirect the user to another form that is partially filled in already from the data I gathered from that file.
I've been reading the docs and found something on multipart forms, but don't know if this is what I should be looking into. I've found example code on uploading files and how to build forms (love Django docs!), but I'm not sure how to tie the two together.
A potential problem I've thought of is how to make sure that a user doesn't somehow skip to the other form without uploading a file. The second form should only be accessible after uploading the file and having it verified for the info I need from it.

You probably want to store the parsed information from the file in the session. That way you can check when displaying the form if the data exists in the session, and if not redirect back to the upload form. If it does exist, you can simply use it as the initial data for the form.

Related

How do web apps receive/process uploaded images?

I can't seem to wrap my head around it. How do websites create forms for image uploads, store, and process it for display on their sites? My current situation is with django storing images.
You place a <form> on your page. It can have different inputs in it, like text, numbers, etc. There is also file input. Then the user submits the form and all data is sent to the webserver. The webserver, basically, receives the file as an array of bytes. You can read more about it here.
In case of Django you'll receive this data in request.FILES. You'll get name, size and other data of the file selected by user. You can then save it on disk or in your database. Read about Django-specific things here.
In general (in a very resumed/simplistic way):
A web page renders a form with an widget in it.
When you tell the browser what's the file you want to upload, it prepare an HTTP request to the webserver in which it stores the binary data of the file.
The request is sent to the web server through a TCP connection.
The server takes the request, see the file an decides what to do with it (depending on configuration files)
Later, the program handling the request, ask the global variables of the server (or something like that) what the heck it did with it files
The server give it the address where it was stored
The app do the rest of the job with the file uploaded :)
In Django:
Three first step are the same
The server ask django what to do with the file
Depending on settings.py the file is uploaded to memory or to a temporary file in disk
The application handles the file accessing it to request.FILES dictionary in your view
When you have it, you can pass it to your models, forms or do whatever you want.
If you want to go deeper with Django file uploads, this section of the documentation is really good. You can take a look at it.
Hope this helps!

Download a generated file and redirect in Django

I have a form with which users submit data to my application, and the response to submitting the form is a download with data depending on what they submitted. Since the submission affects the data in the database I want to redirect from this page to prevent the submission accidentally being made twice.
The only solution I've come across is to save the file on the server and redirect to a page which causes the file to download. However I don't really want to be keeping these files or having to manage them on the server.
Is there a way to download the file and then cause the page to redirect?
Consider also the case when the user's internet connection happens to break during the download. Should the user have a possibility to request the same download again in this case? Then you need to store either the generated file or all data needed to regenerate it anyway.
presumably there are two parts to your code, one adding their data to your db, and a second generating their download. could you just do the first part on form submit, and then redirect them (perhaps including some get parameters) to a second page which reads the db and generates their download?

django admin uploaded file processing

Here's what I want to do, and I did not find something similar in my search so far.
In my admin page, I have a Filefield in my model. The rest of the fields are all read only.
I want to be able to upload a file and process it immediately and to extract info from it to assign to these read only fields.
I thought of overriding the clean_(modelfield) method for this FileField and do this parsing and assigning stuff in it. But this is not done right after the file is uploaded, right? I thought this is done when the form/entry is saved.
Next I thought of adding a custom button to this admin form called 'process' which can be clicked after the file is uploaded. This would trigger the assignment of values to the read only fields.
But I am not able to decide on what is the best approach to process the file and display the updated fields in one page without too much of tinkering.
Any thoughts? Thanks
There are two solutions that I can think of with my limited knowledge. Since, by default, the file upload will only start once the request is posted, an alternative way needs to be designed.
1. Upload file via a script and process the file: Use a script (eg: JQuery script) to upload the file and once upload is complete, trigger a script (onComplete event) to render the values into read-only field. This entire process can be associated to your "Process" button or a time-delayed trigger once the FileField is changed.
2 Custom form for file upload: You can detach the file field and other fields (read only fields that you mentioned). If you design a custom form with just the file upload field and once the user submits the request, you can render another form with rendered initial values in the read only fields. That way you need not have any script but you will have to have 2 forms.
Hope this helps. If you find any other solution, do share it :)

Prompt a confirmation page for a form with FileInput field in Django

I'm developing an admin interface (without a model) for a data restore process. The form on the page allows user to upload a restore file. Now, what I'd like to do is, when the user submit the form, I want to upload the file first, pre-process it, then show a confirmation page to user.
In the pre-process, assuming the form is valid, I unpackage the restore file and extract the backup time from it, then show the backup time (and possibly other information from the restore file) to user in the confirmation page.
My problem is I don't know what the best way is to save the file state. Ideally I'd like to pass the uploaded file to the confirmation page form then when user agrees to continue, I use the restore file to actually restore the system. However, I can't seem to figure out how to do it.
So what I did was to save the file first, then somehow include the filepath in the confirmation page in a hidden field. However, there's a security risk by doing this since the filepath can be modified when user submits the confirmation form.
What's the best way to tackle this problem?
Thanks!
Store the filepath location in the session. You can access the session from your view:
def your_view(request):
...
request.session['file_path'] = 'the file path'
Then in another view get it out:
def your_other_view(request):
...
request.session.get('file_path')
and pass it to your template for use.
You don't have to worry about security, (from the Django docs):
It stores data on the server side and abstracts the sending and receiving of cookies. Cookies contain a session ID – not the data itself.
I tend to solve this problem using a model, that keeps track of a file, and when it was last updated/uploaded. That way in your hidden input you can embed an ID you retrieve later - so if an attacker wants to mess with your form field, all they're going to get is a different backup file (and you could probably write extra validation to handle that).
I'd recommend you create a temporary model to handle your file for you, and then just delete it when you're done processing the file (at the end of the second step).

upload field of an invalid form points to nowhere

This may be a question with a very simple answer, however I couldn't come across to one on the internet.
I am writing a Django application. I have a form with an unrequired ImageField. After the user has submitted the form (with an image), if the form is invalid, on the serverside I populate the form with the request data and files (eg: form = FooForm(request.DATA, request.FILES, instance = foo)and send the response back to the client.
On the client the other fields are displayed OK, but the image field doesn't point to anywhere. As the image field is not required, the user usually overlooks the situation and resubmits the form without the image.
I am lost on even whether this is an issue or this is how it is expected to work anyway. If this is an issue please state so that I provide more details.
This is an unavoidable result of the way browser security works. It's not possible for any server-side system to set the initial value of a file upload field, as it does for any other input field. This is to stop malicious sites uploading content from your computer without your permission - otherwise, a site could set the field to default to your password file, for example.
Obviously, this is is a problem if you actually want the file the user uploaded - if the form was initially invalid, it won't have been saved, and the second time through the file will be lost unless the user uploads it again. One possible solution might be to put the file upload on its own form as a second page - once the form has been validated and saved, the second form is displayed which only has the file on it. The Trac bugtracker works like this, by having a checkbox on the main form for 'I have a file to upload', and taking the user to that form if the checkbox is selected.