Reputation: 467
I am receiving the error is not JSON serializable when I attempt to do the below in my view. Could someone please assist - I am completely unfamiliar with what this means.
views.py
....
def PackingListView(request):
if request.method == "POST":
form = PackingListForm(request.POST)
if form.is_valid():
if 'preview' in request.POST:
request.session['data'] = form.cleaned_data
return redirect('myview')
elif 'save' in request.POST:
form.save()
context = request.session['data'] = form.cleaned_data #get the from the form
pdf = render_to_pdf('packlist_preview.html', context) #create the PDF
filename = "YourPDF_Order{}.pdf" #name the PDF
instance = PackingListDocuments.objects.create() #create a new instance in the model to contain the doc
instance_key = instance.pk #get the pk of that new model object
object = PackingListDocuments.objects.get(pk=instance_key) #get that object
object.Reference_Number = form.cleaned_data.get('Reference_Number')
object.PackingListDocument.save(filename, File(BytesIO(pdf.content))) #save the document to that object
messages.success(request, "Success: Packing List Has Been Created!")
return redirect('HomeView')
else:
form = PackingListForm()
return render(request, 'packlist.html', {'form': form})
Reference_Number
is a foreignkey to the Shipment model which I suppose is why I'm getting this error but I have no idea why or what I might do differently
models.py
class Shipment(models.Model):
Reference_Number = models.CharField(max_length=100)
Ultimate_Consignee = models.CharField(max_length=100)
class PackingListDocuments(models.Model):
Reference_Number = models.ForeignKey(Shipment, null=True, default=None)
PackingListDocument = models.FileField(upload_to='media')
forms.py
class PackingListForm(forms.ModelForm):
class Meta:
model = PackingList
fields = ['Exporter', 'Consignee', 'Reference_Number', ...]
TRACEBACK
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/create/packing_list
Django Version: 1.11
Python Version: 2.7.10
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'Poseidon',
'crispy_forms',
'bootstrap_modal_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/Library/Python/2.7/site-packages/django/utils/deprecation.py" in __call__
142. response = self.process_response(request, response)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/middleware.py" in process_response
58. request.session.save()
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py" in save
83. obj = self.create_model_instance(data)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py" in create_model_instance
69. session_data=self.encode(data),
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py" in encode
98. serialized = self.serializer().dumps(session_dict)
File "/Library/Python/2.7/site-packages/django/core/signing.py" in dumps
93. return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py" in dumps
250. sort_keys=sort_keys, **kw).encode(obj)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py" in encode
207. chunks = self.iterencode(o, _one_shot=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py" in iterencode
270. return _iterencode(o, 0)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py" in default
184. raise TypeError(repr(o) + " is not JSON serializable")
Exception Type: TypeError at /create/packing_list
Exception Value: <Shipment: 219002> is not JSON serializable
Upvotes: 0
Views: 546
Reputation: 3721
Okay, I haven't worked on Django 1.11 in a while but it looks like there's some duplication and you can let the model form do more of the work for you. I can't test it but I think your view should be more like:
elif 'save' in request.POST:
# get a packing list doc from our form but don't save to the db yet
packing_list_doc = form.save(commit=False)
context = request.session['data'] = form.cleaned_data # get the from the form
pdf = render_to_pdf('packlist_preview.html', context) # create the PDF
# what's the point of this? we never use filename...
filename = "YourPDF_Order{}.pdf" # name the PDF
# we already have our packing_list_doc so no need to create one or query one
# also, the form should have already set the shipment/reference_number on our packing_list_doc
# for the love of God, please rename PackingListDocument to packing_list_pdf or similar
# PackingListDocuments.PackingListDocument is not an easy read
packing_list_doc.PackingListDocument = File(BytesIO(pdf.content))
packing_list_doc.save() # because we did commit=False earlier
messages.success(request, "Success: Packing List Has Been Created!")
return redirect('HomeView')
Upvotes: 1
Reputation: 20682
You're storing data in your session and to do that, Django needs to serialise the data, read this. You'll read that the default serializer used is the JSONSerializer
.
Now form.cleaned_data
isn't necessarily serialisable to JSON. Any foreign key submitted as integer (id
) becomes the actual object in cleaned_data
. E.g. form.cleaned_data['Reference_Number']
is a Shipment
instance, not its id
.
So session['data'] = form.cleaned_data
is raising this error.
You need to manually create the dictionary you want to store in the session to ensure it's serialisable.
Upvotes: 2