How to manipulate user uploaded files in django without saving it? - python

I'm making an app which gets data from a csv file and generates a graph using it. All files contains the same structure. I've decided I'm not going to store the files, because of server prices. I'm going to use heroku for now to host this app. It's a Django app. I'm wondering how I could only open the file and extract the data of it using django. I've thought about creating a model and save each file content on it. How can I do this? Is this the best option for my case?

I'll assume you're using Django 1.9 (if not, please update your question to reflect your version of Django).
First, using the HTML <form> tag, you'll want to include enctype="multipart/form-data" as an attribute.
Assuming you'll name your <input> tag as myFile (<form name="myFile">), in your view, simply extract the file from request.FILES:
def my_file_upload(request):
if request.method == 'POST':
myFile = request.FILES.get('myFile')
# At this point, myFile is an instance of UploadedFile, see
# https://docs.djangoproject.com/en/1.9/ref/files/uploads/ for details
Read up on uploaded files in the Django documentation to see the caveats associated with this approach.

Related

How do I automatically upload an automatically created file to a FileField in django? (or equivalent functionality)

I have a method that creates a csv file from a serialized model and writes the file to a data folder. This works - the csv is created, but to do anything with it a user has to manually upload it back in to the app, which is awkward.
I'd like to automate the step of uploading that same file to the UploadFile model in another app within the same project - that is, when it is created, instead of, or in addition to, being written to the file tree, the file is uploaded and stored in a FileField (or location anyway) in an UploadedFile.
EDIT: In this app - a user fills out several forms which, taken together, create a Group. The Group model has a many-2-many relationship to a People model, which has many-2-many relationships to the Attribute and Stats models. Each model has an associated form.
So a user would create a Group, submit it which writes it to the data folder, and then -<(magic happens)>- the Group.name, Group.label, and Group.data are applied to the UploadFileForm which uploads it to the UploadFile model.
I have searched google for something like this and found nothing -- which makes me think I am forming the question incorrectly. Any help is appreciated.
I'll post my code if need be, but a general solution would be helpful enough.
EDIT: I realize now that I can't use 'initial' to populate a FileField in a django mode -- security risk. Since that won't work - I'm out of ideas for how to upload the last file created to a FileField in a django model by any means.

Where to run Python Code in Django once the file is uploaded?

My django application has a file uploader which uploads to a specific location in my local system.
It redirects to a new html page which shows successful message after upload is done.
Once the file is uploaded I need to do some processing of csv files.
I have a python code which does the processing.
Now my question is, where do I put the python file in the django project and how do i call it to be run once the upload is done?
Any help is appreciable
Thanks in advance
You can place it anywhere you like, it's just Python. Maybe in a csv_processing.py if it fits in a single module, or as a completely independent library if it's more. Django doesn't have an opinion on this.
The best way to run it is by doing it asynchronously using Celery.
Make sure the file is within a python package, you do this by adding init.py to the directory, documentation here. In accordance to Django convention; you would place the file within the app that needs to use it, or within another app you would name utils, documentation here.
Question:
I need the file to be run completely after the application uploads the file.
Answer:
new = Storage()
new.file = request.FILES['file']
new.save()
Now we have the database id. (When file object saved into database it emits the id).
originalObj = Storage.objects.get(pk=new.id)
Now you can import the csv file and do modification here.

Django Modal save() function not implemented, using google app engine dev server and mysql

First of all, I want to clarify that I searched everywhere on google & stackoverflow and I couldn't find the solution to the problem I'm having, so this post might seem like a repost but it is not.
Background Info: I am using Django with mysql as the backend, I'm trying to deploy django app onto google app engine with cloud sql instance enabled.
Problem:
I am currently testing the app on google app engine dev. server, the problem I'm having is
that I am trying to upload a video file and an image file using a form and it doesn't work for some reason. It worked on django inbuilt server.
This is what I what I did so far:
I came to know that images could only be stored in blobs, so without re-inventing the wheel, I quickly downloaded and installed django-filetransfers which I believe uploads file using blobs. I followed the instructions as specified on the website(http://www.allbuttonspressed.com/projects/django-filetransfers#documentation), it still did not work.
The code snippet looks like as follows:
view_url = reverse('myapp.views.myview')
if request.method == 'POST':
form = MyForm(request.POST,request.FILES)
if form.is_valid():
form.save_project(request.user)
return HttpResponseRedirect(view_url)
upload_url, upload_data = prepare_upload(request, view_url)
form = MyForm(label_suffix='')
template_var = {'form': form,
'upload_url':upload_url,
'upload_data':upload_data}
return render(request,'mypage.html',template_var)
Following function is inside forms.py file under class MyForm:
def save_project(self,user,commit=True):
inst = super(MyForm,self).save(commit=False)
inst.user = user
if commit:
inst.save()
return inst
Straight forward code, nothing complicated. When I run it on google dev server, it gives an error at inst.save() saying OSERROR, [Errno 40] Function not implemented and it gets traced to os.makedirs(directory) in "django\core\files\storage.py in _save".
I googled more and came to know google app engine doesn't do writes? What does that even mean and how am I suppose to save the data then?
I've been trying to make my django app work on google dev server since last 2 days, after going through all kinds of hurdles, now I'm stuck at this and its very frustrating. I would really appreciate if someone could give me a precise and clear information on "how to upload files through forms on gae dev server using django orm since I'm using Mysql".
Thanks.
As you've discovered, Appengine does not permit you to save files to a local disk. You will need to store them somewhere else. You could put them in MySQL or you could save them to a distributed store like Google Blobstore or Cloud Storage. GCS even has the ability to serve the images that you upload so that you don't have to take that traffic yourself. This is very nice in that it completely offloads file upload and file serving traffic from your GAE instances.
Here is a snippet from GAE Blobstore API docs describing how you'd go about delegating all this to the blobstore service:
The user creates a blob by submitting an HTML form that includes one
or more file input fields. Your application calls create_upload_url()
to get the destination (action) of this form, passing the function a
URL path of a handler in your application. When the user submits the
form, the user's browser uploads the specified files directly to the
Blobstore. The Blobstore rewrites the user's request and stores the
uploaded file data, replacing the uploaded file data with one or more
corresponding blob keys, then passes the rewritten request to the
handler at the URL path you provided to create_upload_url(). This
handler can do additional processing based on the blob key.
https://developers.google.com/appengine/docs/python/blobstore/#Python_Uploading_a_blob
You can then save a reference (key) to that blog in a field in your SQL table.
If this method isn't suitable for you and you must store the data somewhere else, Django does provide a way for you to override the default file upload handling.
https://docs.djangoproject.com/en/dev/ref/files/uploads/#custom-upload-handlers
But be aware that you will now be streaming all that data through your GAE instance and have to keep in mind any limitations that may have (e.g. memory limits, increased load/cost on your instances ...).
Hope that helps.

Loading an external template in GAE application?

Is there a way to load a template from a source which is not hosted on the application itself? For example, in order to load a template on the application itself (hosted by the appengine app):
html = template.render("admin/my_template.html", params)
I would like to do something like:
html = template.render("http://www.otherhost.com/external_template.html", params)
Is there a mechanism to allow such a behavior?
Thanks
Ofcourse you can load templates from other apps. To load templates you have to fetch the templates.
But using an editor is also not very difficult. I use codemirror to edit a HTML textarea.
See this list of demos : http://codemirror.net/demo/
Editing a Jinja txt mail template example:
Templates are just strings. If you can get the text, you can parse it as a template.
In this case you would need to make a request for the file using urllib, get the response, and then use template.Template(content) to convert it to a template object.
However, I must say I still think keeping it in the datastore is a better bet. I'm not sure why you would need an editor for that - why not just cut and paste the content into a field in the GAE admin console, or using the remote API to set it?

Multiple pdf upload from django admin

I am creating an application in django where I want to upload multiple file from django admin. I also want these files to be associated with a particular user in my database. for e.g a pdf file will have a file names as 'john.pdf', 'matt.pdf', 'alice.pdf' and I want to upload all these files at once from django admin and each file should be associated with particular user, so if user john logs in he can see pdf 'john.pdf' in his profile page.
I am new to django and web programming and I have been banging my head for a couple of days but I just cannot find the right logic to implement such a code.
I have looked in these resources but I still cannot really find an answer
How to upload multiple file in django admin models
How to upload through django admin.
I am using django with mysql database. I highly appreciate and thank anyone in advance who could help me out with this problem. (hoping not to get downvoted too much)
Ok so I found out a solution but I still don't know if thats the best solution there. What I did was to add path of my pdf files in MySQL database and add attributes to those paths. I wrote a script in python to add those files to MySQL database. My script listed all the files in the directory, where the files were stored and added them to the database. From these attributes I could retrieve those paths. As these are just paths to static files I had to save them in the static folder for django to access and display them and the rest was simple.

Categories