How to add files in Django session? - django

I want to get some files from the user and after getting the files, I want the user should make a payment after payment is done, an order should be created and the files should be stored against that order in the Database. I know how to create an order and store the files in a database.
I have used Django's sessions to store the string data. But want to store files also. I have used the following code :
In HTML:
<form method="POST" enctype="multipart/form-data">
<input type="file" name="filename">
</form>
In views.py :
if request.method == "POST":
request.session['filename'] = request.FILES['filename']
It throws errors as :
Object of type InMemoryUploadedFile is not JSON serializable

This error been thrown because you're not allowed to put non-serializable objects into the session.
You may encounter this problem by saving it on the server and just save in the session the file name for future usage.
See more:
Python and Django - How to use in memory and temporary files

Related

How to change settings variable to be different for every user

MY views.py
def change_currency(request):
settings.CURRENCY = request.POST['currency']
return HttpResponseRedirect('/')
My settings.py
CURRENCY = 'EUR'
My form
<form action="{% url 'change_currency' %}"
method="POST" class="currency">
EUR
{% csrf_token %}
<input style="display: none" value="EUR" name="currency">
</form>
Problem 1
If I manually change the settings.CURRENCY variable in everything works like a charm, but if I make a form and try to change the settings.CURRENCY it doesn't work
Problem 2
Will it be possible to have a variable in settings.py that change for different users
Problem 3
I can't use sessions, beause i use settings.CURRENCY in filters.py and I don't know how to use request.session in filters.py
First of all you can access request and therefore session in filter.
The solution you try to use does not work for several reasons.
Settings are imported once
When you import module object like this into another module (for example myapp.views):
from settings import CURRENCY
the changes done to settings.CURRENCY will not be visible in the views module. The import happens once and the value at import time is bound to variable in the module.
Multiple workers
Even if you change the variable in views module there is another problem. If you are running non develop server (like gunicorn) it starts several processes to handle requests. It may happen that a change done to settings is processed by one process and the next request is processed by another worker which has the old value.
There should be one place where this settings is stored. Session is a good place as it is global and private to user.

Django file upload without model and posted using ajax

How to save a file, uploaded from a form to a local directory without using model? Also the form is being posted using ajax, so how do I render the file information from the html file?
Create an HTML form with
<form method="post" enctype="multipart/form-data" action="your_view_name">
<input name="myfile" type="file" />
</form>
Use AJAX to post the file. If you're using jQuery, see this link on how to post stuff
http://api.jquery.com/jquery.post/
In the view, use request.FILES to access the uploaded file. Use whatever Python APIs you have to save the file to the disk.

Using forms only for validation

Say you already have a complex HTML form, possible from a designer, front end dev, etc. Is it common practice to not use dynamic forms (based on a Django form) for complicated forms?
I want to do something like this:
1.) Create custom HTML form.
2.) Catch form data through POST request, put it in an object/dictionary.
3.) Do some manipulations with that data to get it in a format acceptable by a Django form.
4.) Pass the manipulated data in to a form object, validate it, etc...
What is a clear solution to this problem? Should I be using Django's dynamic forms for everything? If not - how do I implement the above?
EDIT:
Part of my question has to do with using the forms ONLY for validation. I don't think I made this clear. Here is what I'm trying to do:
template.html
<form method="post">
{% csrf_token %}
<input class="foo" name="bar" type="text" value=""/>
<!-- Some more fields, not rendered through Django form -->
<button type="submit">Create Object</button>
</form>
As you can see, other than the csrf_token there is no Django code here. What I am trying to do in my view is catch the data in the POST in my view, make some changes to the data, then try to bind the new data to a form (not sure if it's possible):
views.py
def my_view(request):
# Some GET code
if request.method == 'POST':
form = ImportedForm(request.POST)
form.data['foo'] = "newValue"
# Now after changing the data, validate it...
If the form and model match nicely then I'll take advantage of the ModelForm functionality.
But most of the time it is not so tidy so, most typically, I do things in about this order:
create a django form with all the field definitions
create django GET view to serve the empty form
create an html template which serves the default html/form
test the blank form
create the POST routine to call validation and reserve the validated (erroneous) form
modify the django form to validate the fields
modify the html form to serve the error messages
test the validation and error messages
modify the POST routine to handle a valid form and do whatever it should do as a result (might involve a redirect and 'thanks' view/template)
Test the whole lot
let the designer loose on the templates
In truth the designer will be involved at some points earlier along the way but in theory I just get it all to work as a "white" then add all the fancy stuff after. That includes javascript validation (ie after all the above).
I ended up doing something like this. It is ugly, and may not be the proper way to do it, but it works...
if request.method == 'POST':
try:
# Create dictionary from POST data
data = {
'foo': request.POST['foo'],
'foobar': request.POST['foobar'],
}
except:
# Handle exceptions
form = ImportedForm(data)
if form.is_valid:
# Continue to validate and save

Using FileField in a FormWizard (Django 1.3)

I am trying to use a Django 1.3 FormWizard to upload a file with 2 steps:
1. Only the FileField
2. If the file was correctly uploaded and valid (after custom validation), offer to give it a name and description.
Following the documentation, I wrote:
class CreateCheckWizard(FormWizard):
def done(self, request, form_list):
return HttpResponseRedirect('/my_checks/')
def get_template(self, step):
return ['create_check_%s.html' % step, 'create_check_1.html']
class CreateCheckForm1(forms.Form):
my_file = forms.FileField()
class CreateCheckForm2(forms.Form):
title = forms.CharField(max_length=255)
I added the multipart/form-data to the FORM tag in the template:
<form enctype="multipart/form-data" action="." method="post">
However, even if I upload a file, I get the error "This field is required."
I guess the form is created omitting the request.FILES field.
How can we change that behaviour to successfully upload files in the FormWizard?
Edit: Looking at Django source code, it indeed create the forms using form(request.POST) instead of form(request.POST, request.FILES) like it should be to handle files.
Any way to upload files without changing the source code?
This isn't possible in the Django 1.3 form wizard. From the Django form wizard docs:
Important limitation: Because the wizard uses HTML hidden fields to store data between pages, you may not include a FileField in any form except the last one
It is possible with the Django 1.4 form wizard (see handling files docs). If you're using Django 1.3, you can install the new form wizard as a separate app.

Django - HTTP Uploading of Multiple Images

I looked at this question:
Uploading multiple files with Django
but it did not seem to help as I have issues regarding it:
I don't want to deal with flash sessions using SWF Upload and Uploadify because I need to do uploads that only authenticated users can do.
newforms are for older versions of django, I am using 1.3
Using Django, how can I have this HTML form structure:
<form enctype="multipart/form-data" action="." method="post">
<label for="id_image_1">Image 1</label>
<input type="file" name="image[]" id="id_image_1" />
<label for="id_image_2">Image 2</label>
<input type="file" name="image[]" id="id_image_2" />
</form>
and handle it using a view?
If you have a fixed number of filefields, you could simply define a form with enough filefields, or add filefields programatically in a form's constructor. See the Django docs on File Uploads.
If you want some sort of dynamic functionality (a la gmail's "add another file"), then you could define a formset using a form with a single filefield. Display a single form initially and when you want to add another, use a little javascript to produce the new form and update the formset's management form. There are a number of snippets floating around to help you do this, though they may need some tweaking. See the Django docs on File Uploads and Formsets.
Another option may be to use a custom widget and field, though I have not reviewed or tried this.
On the off-chance you aren't aware, the name="image[]" scheme is PHP specific and has no special meaning in other languages, unless you reimplement it.
newforms is what the current forms were called before 1.0. Furthermore, if you got your form validated, http://docs.djangoproject.com/en/dev/topics/http/file-uploads/, you'll have your files as a list (tuple, probably, but sequence anyway) in request.FILES['image'], so just do:
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
for f in request.FILES['image']:
handle_uploaded_file(f)
You'll have to write handle_uploaded_file yourself, the URL explains how