Marshmallow Invalid input type on nesting - python

I wrote a nested schema. but whenever i pass the json from postman it shows invalid input type.
here is the code below:
class ChalanProductsSchema(Schema):
product_id = fields.Str(required=True)
class ChalanDetailsSchema(Schema):
chalan_id = fields.Str(required=True)
rows = fields.Nested(ChalanProductsSchema, many=True)
chalan_details_Schema = ChalanDetailsSchema(many=True)
# serializing json
data = chalan_details_Schema.load(json_data)
#json i pass from postman
{
"chalan_id":"2022.08.0002",
"rows":[
{
"product_id":"XXXXXXXX1"
},
{
"product_id":"XXXXXXXX2"
}
]
}
Error I am having:
{
"_schema": [
"Invalid input type."
]
}

Looks like you don't expect multiple ChalanDetail
Try to change
chalan_details_Schema = ChalanDetailsSchema(many=True)
into
chalan_details_Schema = ChalanDetailsSchema()

Related

Marshmallow: dynamically choose Schema depending on data?

For googlers also that question in github.
I had users of 2 types. I need to validate user data by one of 2 schemas.
I prepare awesome scratch with code of my idea, of course its not working.
class ExtraType0(Schema):
nickname = fields.String()
class ExtraType1(Schema):
id = fields.Integer()
class UserSchema(Schema):
type = fields.String()
extra = fields.Method(deserialize="get_extra_schema_by_user_type")
def get_extra_schema_by_user_type(self, obj):
if obj == 0:
# call ExtraType0 scheme and its (de)serialization
return fields.Nested(ExtraType0())
else:
# call ExtraType01scheme and its (de)serialization
return fields.Nested(ExtraType1())
# correct data
result = UserSchema().load(
{
"type": 0,
"extra": {
"id": 0
}
})
# also correct data
result1 = UserSchema().load(
{
"type": 1,
"extra": {
"nickname": "user123"
}
})
How I can proper choose schema depends on loaded in type field data?

how to return a list of dictionary in graphene?

I am new on graphql and working with some datasets that is returned as a list of dictionaries.
snippet code:
class Player(ObjectType):
username = String()
role = String()
class Game(ObjectType):
players = List(Player)
I'm wondering why below code doesn't work?
class Query(ObjectType):
game_info = Field(Game, username=String(), role=String())
def resolve_game_info(self, info):
results = [{
"username":"Malphite",
"role":"tank"
},
{
"username":"Teemo",
"role":"support"
}]
output = []
for res in results:
output.append(
Player(
username=res['username'],
role=res['role']
)
)
return output
How I query in graphql:
query {
game_info(username:"Teemo") {
players {
username
role
}
}
}
Results to like this:
{
"data": {
"gameInfo": null
}
}
Any help would this would be greatly appreciated!
The problem seems in format of returned data. Suppose, you have more fields in your Game, not only players. There is no way of including those fields in your return format.
Instead of return output .
Try: return {'players':output}

Django - How to map object from another API and send in GET response

I would like to map object from another API and send in GET response. I'm going to change only id of received object. Let's assume I get data from another API in such format:
{
"id": "31242",
"name": "sth1",
"price": "44",
"data": "2017-06-07",
}
In my database I have table object1 with values:
{
"id": "123",
"name": "sth1",
},
{
"id": "124",
"name": "sth2",
},
{
"id": "125",
"name": "sth3",
}
Field name is unique both in data from API and in data from database. I receive an object named sth1. So now I would like to find it in my database and get his id, replace with id from API and send GET response. In this case my response would look in this way:
{
"id": "123",
"name": "sth1",
"price": "44",
"data": "2017-06-07",
}
At this moment this is my URL - url(r'^data/(?P<name>\w+)$', views.DataList),
but I would like to have such URL - localhost:8000/data?name=sth
Myview.py:
#api_view(['GET'])
def DataList(request, name=None):
if request.method == 'GET':
quote = getDataFromAPI().get(name)
return Response(quote)
serializers.py:
class Object1Serializer(serializers.ModelSerializer):
class Meta:
model = Object1
depth = 1
fields = '__all__'
models.py:
class Object1(models.Model):
name = models.CharField(max_length=200)
I have done it in this way:
#api_view(['GET'])
def DataList(request):
t = request.GET.get("t","")
quote = getDataFromAPI().get(t)
id = Object1.objects.get(t=t)
quote["id"] = id
return Response(quote)
But I get error:
TypeError: Object of type 'Object1' is not JSON serializable
I suppose, your view should look somewhat like this,
#api_view(['GET'])
def DataList(request):
t = request.GET.get("t","")
quote = getDataFromAPI().get(t)
id = Object1.objects.get(t=t).id #put the id of the object in the variable.
#not the object itself.
quote["id"] = id
return Response(quote)
If you want to change the url from
url(r'^data/(?P<name>\w+)$', views.DataList) to localhost:8000/data?name=sth you'd need to change your api endpoint from
#api_view(['GET'])
def DataList(request, name=None):
to
#api_view(['GET'])
def DataList(request):
name = request.GET.get("name","")
and then take the id of object from your database by querying
id = Object1.objects.get(name=name)
and then updating id in response to be sent
quote["id"] = id

Serialize a string without changes in Django Rest Framework?

I'm using Python's json.dumps() to convert an array to a string and then store it in a Django Model. I'm trying to figure out how I can get Django's REST framework to ignore this field and send it 'as is' without serializing it a second time.
For example, if the model looks like this(Both fields are CharFields):
name = "E:\"
path_with_ids= "[{"name": "E:\", "id": 525}]"
I want the REST framework to ignore 'path_with_ids' when serializing so the JSON output will look like this:
{ "name": "E:\", "path_with_ids":
[ {"name": "E:\", "id": 525} ] }
and not like this:
{
"name": "E:\",
"path_with_ids": "[{\"name\": \"E:\\\", \"id\": 525}]" }
I've tried to make another serializer class that spits out the input it gets 'as is' without success:
Serializers.py:
class PathWithIds(serializers.CharField):
def to_representation(self, value):
return value.path_with_ids
class FolderSerializer(serializers.ModelSerializer):
field_to_ignore = PathWithIds(source='path_with_ids')
class Meta:
model = Folder
fields = ['id', 'field_to_ignore']
Please help!
I ended up using a wasteful and sickening method of deserializing the array before serializing it again with the REST framework:
Serializers.py:
import json
class PathWithIds(serializers.CharField):
def to_representation(self, value):
x = json.loads(value)
return x
class FolderSerializer(serializers.ModelSerializer):
array_output = PathWithIds(source='field_to_ignore')
class Meta:
model = Folder
fields = ['id', 'array_output']
Output in the rest API:
{
"name": "E:\",
"array_output": [
{
"name": "E:\",
"id": 525
}
] }

Serializing nested object to string in Django Rest Framework

I am trying to connect my Django application to the mailchimps API with help from the Django Rest Framework, if I want to create a batch operation, I need to send the following call:
{
"operations": [
{
"method": "PUT",
"path": "lists/abc123/members/817f1571000f0b843c2b8a6982813db2",
"body": "{\"email_address\":\"hall#hallandoates.com\", \"status_if_new\":\"subscribed\"}"
},...
]
}
As you can see, the body object should be a json string. To create these calls, I created a model operation:
models.py
class Operation(object):
def __init__(self, method, list, contact):
email_clean = contact.email_address.lower().encode('utf-8')
subscriber_hash = hashlib.md5(email_clean).hexdigest()
serializer = ContactSerializer(contact)
body = serializer.data
self.method = method
self.path = "lists/%s/members/%s" % (list, subscriber_hash)
self.body = body
And the following serializer:
serializer.py
class OperationSerializer(serializers.Serializer):
method = serializers.CharField()
path = serializers.CharField()
body = serializers.CharField(allow_blank=True, required=False)
When I use my serializer to generate JSON, and parse the data with JSONRenderer(), the following call is returned:
{
"operations": [
{
"method": "PUT",
"path": "lists/abc123/members/817f1571000f0b843c2b8a6982813db2",
"body": "{\'email_address\':\'hall#hallandoates.com\', \'status_if_new\':\'subscribed\'}"
},...
]
}
This call breaks because of the single quotes, can anyone help me a hand in solving this?

Categories

Resources