Whle converting dict to serializer, serializer.is_valid always False in Django - json

My cmd:
python manage.py shell
from user.models import UserInfo
from user.serializers import UserInfoSerializer
import io
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
u=UserInfo.objects.all()[0]
s=UserInfoSerializer(u)
j=JSONRenderer().render(s.data)
o=io.BytesIO(j)
d=JSONParser().parse(o)
s1=UserInfoSerializer(data=d)
s1.is_valid()
But the issue here is that s1.is_valid() always comes out to be False and I can't save s1 as a serializer.
I'm getting this error:
>>> d
{'username': 'user001', 'password': 'pass001', 'email': 'user001#example.com', 'contact': 9876543210}
>>> s001=UserInfoSerializer(data=d)
>>> s001.is_valid()
False
>>> s001.validated_data()
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'dict' object is not callable
>>> s001.validated_data
{}
>>> s001.data
{'username': 'user001', 'password': 'pass001', 'email': 'user001#example.com', 'contact': 9876543210}
>>> s001.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/imharjyotbagga/PycharmProjects/DRF/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 182, in save
'You cannot call `.save()` on a serializer with invalid data.'
AssertionError: You cannot call `.save()` on a serializer with invalid data.
>>>
So how can I go about this!?

You'd need to show .errors attribute to even try to diagnose the problem. My blind guess would be you messed up your password field. But you won't get any definitive answer unless you produce the code of your serializer, model, and the .errors of your serializer would also be really helpful.

Related

Using json with jsondatetime

json.dumps gives an error if both json and jsondatetime are imported. The error is the following:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/json/__init__.py", line 230, in dumps
return _default_encoder.encode(obj)
TypeError: encode() missing 1 required positional argument: 'o'
But I just import JSON, then json.dumps work fine. I don't know how to deal with this. I need jsondatetime as well
This works::
import json
json.dumps({'DbName': 'DB','Hostname': '10.0.0.6','DbUsername':'SYSTEM'})
'{"Hostname": "10.0.0.6","DbName": "DB", "DbUsername": "SYSTEM"}'
This does not work::
import jsondatetime
import json
json.dumps({'DbName': 'DB', 'Hostname': '10.0.0.6', 'DbUsername': 'SYSTEM'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/json/__init__.py", line 230, in dumps
return _default_encoder.encode(obj)
TypeError: encode() missing 1 required positional argument: 'o'
jsondatetime is a drop-in replacement for json. You should only have
import jsondatetime as json
From the documentation:
JSON-datetime is a very simple wrapper around Python simplejson loads method. It decodes datetime values contained in JSON strings.

Flask TypeError 'is not JSON serializable' - nested dictionary

i am using Flask as framework for my server, and while returning a response i get the following error:
> Traceback (most recent call last):
File "C:\Python27\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Python27\lib\site-packages\flask_restful\__init__.py", line 480, in wrapper
resp = resource(*args, **kwargs)
File "C:\Python27\lib\site-packages\flask\views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "C:\Python27\lib\site-packages\flask_restful\__init__.py", line 595, in dispatch_request
resp = meth(*args, **kwargs)
File "rest.py", line 27, in get
return jsonify(**solution)
File "C:\Python27\lib\site-packages\flask\json.py", line 263, in jsonify
(dumps(data, indent=indent, separators=separators), '\n'),
File "C:\Python27\lib\site-packages\flask\json.py", line 123, in dumps
rv = _json.dumps(obj, **kwargs)
File "C:\Python27\lib\json\__init__.py", line 251, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "C:\Python27\lib\json\encoder.py", line 209, in encode
chunks = list(chunks)
File "C:\Python27\lib\json\encoder.py", line 434, in _iterencode
for chunk in _iterencode_dict(o, _current_indent_level):
File "C:\Python27\lib\json\encoder.py", line 408, in _iterencode_dict
for chunk in chunks:
File "C:\Python27\lib\json\encoder.py", line 332, in _iterencode_list
for chunk in chunks:
File "C:\Python27\lib\json\encoder.py", line 332, in _iterencode_list
for chunk in chunks:
File "C:\Python27\lib\json\encoder.py", line 442, in _iterencode
o = _default(o)
File "C:\Python27\lib\site-packages\flask\json.py", line 80, in default
return _json.JSONEncoder.default(self, o)
File "C:\Python27\lib\json\encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: {'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'} is not JSON serializable
i have the following function:
from flask import Flask, request, jsonify
from flask_restful import Resource, Api
from flask_cors import CORS, cross_origin
from json import dumps
import flights
import solveProblem
app = Flask(__name__)
api = Api(app)
CORS(app)
class Flights(Resource):
def get(self, data):
print 'received data from client: ' + data
solution = solveProblem.solve(data)
print 'got the solution from the script! \nSOLUTION: \n'
print solution
return jsonify(solution)
api.add_resource(Flights, '/flights/<string:data>')
if __name__ == '__main__':
app.run()
while debugging the problem, i found the following solutions which did not work:
1) return solution instead of {'solution': solution}
2) do jsonify(solution)
3) do jsonify(**solution)
none of the above worked for me;
i wonder why this happens, when i am trying to return a valid dictionary:
{'flights': [[{'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'}]], 'cost': '31'}
any help is appreciated.
Thanks
My guess is when you were creating 'solution', the data that got assigned to it was an incorrectly formatted dictionary
{'item', 'value'}
Instead of:
{'item': 'value'}
Thus creating a set instead of a dict
we cannot directly use the jsonify when your trying to converting list of data into json.
there is two approaches are there you can convert list into dictionary for that we need to write function that convert your list data into dictionary which is complicated task .
there is one smart work you can use Marshmallow library . it serialized you list data after that you can use jsonify.
In flask-restful, Resource class get method will just need to return python data structure. So just remove jsonify. For User Defined Object, you can use marshal_with() decorator.
See more: https://flask-restful.readthedocs.io/en/latest/quickstart.html#a-minimal-api
Since most of your functions are declared elsewhere, I worked a toy Flask program just to pass the dictionary you got stuck with.
[Edit] Before I was using the standard python json module. I edited it to use flask's own jsonify, and it works with the direct dictionary still. So the error is not where the OP is looking for.
{'flights': [[{'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'}]], 'cost': '31'}
The following program runs and returns the dictionary as a JSON object:
import flask
app = flask.Flask(__name__)
#app.route('/')
def hello():
jdic = flask.jsonify( {'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'} )
return jdic
if __name__ == '__main__':
app.run()
As I found out, this error generally occurs when the response is not a pure python dictionary. This happened to me because I was trying to pass a class object. So, to solve the problem, i created a class method which returns a dictionary describing the object, and use this to create the json response.
Conclusion: Use Pure python objects, which are easily translated to JSON.
I had the same problem with a 3 level Nested Dictionary; it was valid, json serializable and via command line json.dumps had no issue. However, Flask did not want to output it: "TypeError", not json serializable. The only difference is that I am using Python 3.5.
So I made a copy of it as a string (that on command line was json serializable!) and passed to Flask output, it worked.
Try to pass the nested json as
eval(str(solution))
and see the error. It's not a definitive solution but more a workaround.
Hope it helps.

Python 3 JSON deserializer: JSON object must be str, not 'bytes'

There are couple of questions related to this error:
JSON object must be str, not 'bytes'
However, except obvious solution to read and decode response, I didn't learn anything special.
Here is example to the problem:
>>> import json
>>> from urllib.request import urlopen
>>> url = 'http://echo.jsontest.com/key/value/one/two'
>>> with urlopen(url) as request:
... json.load(request)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "C:\Python35\lib\json\__init__.py", line 268, in load
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
File "C:\Python35\lib\json\__init__.py", line 312, in loads
s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'
So my question is why Python's JSON deserializer (that accepts file-like objects with .read() method), does not try to handle this request, as response headers hint all there is needed to know:
Content-Type: application/json; charset=ISO-8859-1
Headers hint, they do not guarantee, but that can not be a reason not to try the obvious IMHO.
Use json.loads instead of json.load

simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 3 (char 2)

I am trying to send a http request to any url and get the response using urllib library. Following is the code that I have used :
>>> import requests
>>> r = requests.get("http://www.youtube.com/results?bad+blood")
>>> r.status_code
200
when I try to do this I get following error.
>>> r.json()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/requests/models.py", line 808, in json
return complexjson.loads(self.text, **kwargs)
File "/Library/Python/2.7/site-packages/simplejson/__init__.py", line 516, in loads
return _default_decoder.decode(s)
File "/Library/Python/2.7/site-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/Library/Python/2.7/site-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 3 (char 2)
can someone tell me whats wrong with the code.
PS: I am using python 2.7.10
The response isn't JSON, it is 'text/html; charset=utf-8'. If you want to parse it, use something like BeautifulSoup.
>>> import requests, bs4
>>> rsp = requests.get('http://www.youtube.com/results?bad+blood')
>>> rsp.headers['Content-Type']
'text/html; charset=utf-8'
>>> soup = bs4.BeautifulSoup(rsp.content, 'html.parser')
I'd recommend using the YouTube Search API instead. Log in to Google Developers Console, set up a API key following the API Key Setup instructions, then you can make the request using the YouTube Search API:
>>> from urllib import parse
>>> import requests
>>> query = parse.urlencode({'q': 'bad blood',
... 'part': 'snippet',
... 'key': 'OKdE7HRNPP_CzHiuuv8FqkaJhPI2MlO8Nns9vuM'})
>>> url = parse.urlunsplit(('https', 'www.googleapis.com',
... '/youtube/v3/search', query, None))
>>> rsp = requests.get(url, headers={'Accept': 'application/json'})
>>> rsp.raise_for_status()
>>> response = rsp.json()
>>> response.keys()
dict_keys(['pageInfo', 'nextPageToken', 'regionCode', 'etag', 'items', 'kind'])
Note that the example is using Python 3. If you want to use Python 2, then you will have to import urlencode from urllib and urlunsplit from urlparse.
That URL returns HTML, not JSON, so there's no point calling .json() on the response.

python ordered_dict from json

I am using Python 2.6.6, and trying to generate a ordered_dict from json string. I could understand that I could use object_pairs_hook of json Decoder/loads, but unfortunately it's not supported in 2.6.6. Is there any way out?
e.g.
template_s = '{ "aa": {"_type": "T1"}, "bb": {"_type": "T11"}}'
json.loads(template_s, object_pairs_hook=OrderedDict)
>>> json.loads(json_str, object_pairs_hook=OrderedDict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/json/__init__.py", line 318, in loads
return cls(encoding=encoding, **kw).decode(s)
TypeError: __init__() got an unexpected keyword argument 'object_pairs_hook'
Thanks
I was able to do the same with simplejson
import simplejson as json
json.loads(config_str, object_pairs_hook=json.OrderedDict)