The server comes with json format:
{
"type": "string",
"object": {
"lead_id": int,
"form_name": "string",
"answers": [
{
"lead_id": int,
"key": "string",
}
...
]
},
"group_id": int,
"secret": "string"
}
How to use django REST framework to validate this json?
ru version
class AnswersSerializer(serializers.Serializer):
lead_id = serializers.IntegerField(required=True)
key = serializers.CharField(max_length=100)
class ObjectSerializer(serializers.Serializer):
lead_id = serializers.IntegerField(required=True)
form_name = serializers.CharField(max_length=100)
answers = serializers.ListField(child=AnswersSerializer())
class UpdateGroup(serializers.Serializer):
group_id = serializers.IntegerField(required=True)
type = serializers.CharField(max_length=100)
secret = serializers.CharField(max_length=100)
object = serializers.DictField(child=, default={})
Example:
# serializers.py
from rest_framework import serializers
class VkObjectSerializer(serializers.Serializer):
"""
is 'object'
"""
lead_id = serializers.IntegerField()
group_id = serializers.IntegerField()
user_id = serializers.IntegerField()
form_id = serializers.IntegerField()
class VkBaseSerializer(serializers.Serializer):
"""
Base serializer
"""
type = serializers.CharField(max_length=200)
object = VkObjectSerializer()
group_id = serializers.IntegerField()
secret = serializers.CharField(max_length=200)
# view.py
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response
from .serializers import VkBaseSerializer
class VkCallbackView(CreateAPIView):
serializer_class = VkBaseSerializer
def create(self, request, *args, **kwargs):
"""
Method is validate json in view
"""
valid_ser = self.serializer_class(data=request.data)
if valid_ser.is_valid():
return Response('True')
return Response('False')
Valid data:
>>> valid_ser.data
{
"type": "str",
"object": {
"lead_id": 123,
"group_id": 12345,
"user_id": 12352,
"form_id": 1
},
"group_id": 5123,
"secret": "str"
}
The answers were very helpful:
Django Rest Framework ListField and DictField - how to set model json
How to validate a json object in django - validate data in view
You can use django rest framework to write you own validators like so,
class MultipleOf(object):
def __init__(self, base):
self.base = base
def __call__(self, value):
if value % self.base != 0:
message = 'This field must be a multiple of %d.' % self.base
raise serializers.ValidationError(message)
You can find more details here
Hope this helps!
Related
I have a python django rest application that I need it to be able to handle post request for App Store Server Notifications.
Thing is that v2 of the App Store Server Notifications payload is in JSON Web Signature (JWS) format, signed by the App Store. Which contains fields that in turn are also in JSON Web Signature (JWS) format, signed by the App Store. I know how to handle that using python-jose procedurally but I can't figure out how to fit the whole process within Django serializers in a graceful manner with as minimal hacking as possible.
The data could be something like:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJub3RpZmljYXRpb25UeXBlIjoidHlwZSIsInN1YnR5cGUiOiJzdWJfVHlwZSIsIm5vdGlmaWNhdGlvblVVSUQiOiJzdHJpbmcgbm90aWZpY2F0aW9uVVVJRCIsImRhdGEiOnsiYXBwQXBwbGVJZCI6MTIzNCwiYnVuZGxlSWQiOiJhZmRzYXNkIiwiYnVuZGxlVmVyc2lvbiI6ImJ1bmRsZVZlcnNpb24iLCJlbnZpcm9ubWVudCI6ImVudmlyb25tZW50Iiwic2lnbmVkUmVuZXdhbEluZm8iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKaGRYUnZVbVZ1WlhkUWNtOWtkV04wU1dRaU9pSjBaWE4wSUhSdmJHVnRJaXdpWVhWMGIxSmxibVYzVTNSaGRIVnpJam94TENKbGVIQnBjbUYwYVc5dVNXNTBaVzUwSWpvMExDSm5jbUZqWlZCbGNtbHZaRVY0Y0dseVpYTkVZWFJsSWpveE5qTTJOVE0xTVRReExDSnBjMGx1UW1sc2JHbHVaMUpsZEhKNVVHVnlhVzlrSWpwMGNuVmxMQ0p2Wm1abGNrbGtaVzUwYVdacFpYSWlPaUowWlhOMElIUnZiR1Z0SWl3aWIyWm1aWEpVZVhCbElqb3hMQ0p2Y21sbmFXNWhiRlJ5WVc1ellXTjBhVzl1U1dRaU9pSjBaWE4wSUhSdmJHVnRJaXdpY0hKcFkyVkpibU55WldGelpWTjBZWFIxY3lJNk1Td2ljSEp2WkhWamRFbGtJam9pZEdWemRDQjBiMnhsYlNJc0luTnBaMjVsWkVSaGRHVWlPakUyTXpZMU16VXhOREY5LnYwWW9YQUd0MTFPeVBXUk8zV2xTZDRiSWVtcVV6Q0ZJbFdjd0ZwcEI5TmMiLCJzaWduZWRUcmFuc2FjdGlvbkluZm8iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKaGNIQkJZMk52ZFc1MFZHOXJaVzRpT2lKMFpYTjBJSFJ2YkdWdElpd2lZblZ1Wkd4bFNXUWlPaUp6WkdaellYTmtaaUlzSW1WNGNHbHlaWE5FWVhSbElqb3hOak0yTlRNMU1UUXhMQ0pwYmtGd2NFOTNibVZ5YzJocGNGUjVjR1VpT2lKMFpYTjBJSFJ2YkdWdElpd2lhWE5WY0dkeVlXUmxaQ0k2ZEhKMVpTd2liMlptWlhKSlpHVnVkR2xtYVdWeUlqb2lkR1Z6ZENCMGIyeGxiU0lzSW05bVptVnlWSGx3WlNJNk1UUTFMQ0p2Y21sbmFXNWhiRkIxY21Ob1lYTmxSR0YwWlNJNk1UWXpOalV6TlRFME1Td2liM0pwWjJsdVlXeFVjbUZ1YzJGamRHbHZia2xrSWpvaWRHVnpkQ0IwYjJ4bGJTSXNJbkJ5YjJSMVkzUkpaQ0k2SW5SbGMzUWdkRzlzWlcwaUxDSndkWEpqYUdGelpVUmhkR1VpT2pFMk16WTFNelV4TkRFc0luRjFZVzUwYVhSNUlqb3hORFVzSW5KbGRtOWpZWFJwYjI1RVlYUmxJam94TmpNMk5UTTFNVFF4TENKeVpYWnZZMkYwYVc5dVVtVmhjMjl1SWpveE5EVXNJbk5wWjI1bFpFUmhkR1VpT2pFMk16WTFNelV4TkRFc0luTjFZbk5qY21sd2RHbHZia2R5YjNWd1NXUmxiblJwWm1sbGNpSTZJblJsYzNRZ2RHOXNaVzBpTENKMGNtRnVjMkZqZEdsdmJrbGtJam9pZEdWemRDQjBiMnhsYlNJc0luUjVjR1VpT2lKMFpYTjBJSFJ2YkdWdElpd2lkMlZpVDNKa1pYSk1hVzVsU1hSbGJVbGtJam9pZEdWemRDQjBiMnhsYlNKOS5lbnlkTnVwd2txOTNYQ2dfeG5yYzNXTmtNNjM4NXpITnpoa0tqa3cyb3VrIn19.OgSJ4xE3r2Tw0Q4KcwPSD4YFo21uCLDgrKOtKOomijo
and then the part inbetween the dots decoded could look like
b'{"notificationType":"type","subtype":"sub_Type","notificationUUID":"string notificationUUID","data":{"appAppleId":1234,"bundleId":"afdsasd","bundleVersion":"bundleVersion","environment":"environment","signedRenewalInfo":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRvUmVuZXdQcm9kdWN0SWQiOiJ0ZXN0IHRvbGVtIiwiYXV0b1JlbmV3U3RhdHVzIjoxLCJleHBpcmF0aW9uSW50ZW50Ijo0LCJncmFjZVBlcmlvZEV4cGlyZXNEYXRlIjoxNjM2NTM1MTQxLCJpc0luQmlsbGluZ1JldHJ5UGVyaW9kIjp0cnVlLCJvZmZlcklkZW50aWZpZXIiOiJ0ZXN0IHRvbGVtIiwib2ZmZXJUeXBlIjoxLCJvcmlnaW5hbFRyYW5zYWN0aW9uSWQiOiJ0ZXN0IHRvbGVtIiwicHJpY2VJbmNyZWFzZVN0YXR1cyI6MSwicHJvZHVjdElkIjoidGVzdCB0b2xlbSIsInNpZ25lZERhdGUiOjE2MzY1MzUxNDF9.v0YoXAGt11OyPWRO3WlSd4bIemqUzCFIlWcwFppB9Nc","signedTransactionInfo":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBBY2NvdW50VG9rZW4iOiJ0ZXN0IHRvbGVtIiwiYnVuZGxlSWQiOiJzZGZzYXNkZiIsImV4cGlyZXNEYXRlIjoxNjM2NTM1MTQxLCJpbkFwcE93bmVyc2hpcFR5cGUiOiJ0ZXN0IHRvbGVtIiwiaXNVcGdyYWRlZCI6dHJ1ZSwib2ZmZXJJZGVudGlmaWVyIjoidGVzdCB0b2xlbSIsIm9mZmVyVHlwZSI6MTQ1LCJvcmlnaW5hbFB1cmNoYXNlRGF0ZSI6MTYzNjUzNTE0MSwib3JpZ2luYWxUcmFuc2FjdGlvbklkIjoidGVzdCB0b2xlbSIsInByb2R1Y3RJZCI6InRlc3QgdG9sZW0iLCJwdXJjaGFzZURhdGUiOjE2MzY1MzUxNDEsInF1YW50aXR5IjoxNDUsInJldm9jYXRpb25EYXRlIjoxNjM2NTM1MTQxLCJyZXZvY2F0aW9uUmVhc29uIjoxNDUsInNpZ25lZERhdGUiOjE2MzY1MzUxNDEsInN1YnNjcmlwdGlvbkdyb3VwSWRlbnRpZmllciI6InRlc3QgdG9sZW0iLCJ0cmFuc2FjdGlvbklkIjoidGVzdCB0b2xlbSIsInR5cGUiOiJ0ZXN0IHRvbGVtIiwid2ViT3JkZXJMaW5lSXRlbUlkIjoidGVzdCB0b2xlbSJ9.enydNupwkq93XCg_xnrc3WNkM6385zHNzhkKjkw2ouk"}}'
and then if the fields encoded in jws format are also decoded the same way mentioned aboce it is going to ultimately look like this:
{
"notificationType":"type",
"subtype":"sub_Type",
"notificationUUID":"string notificationUUID",
"data":
{"appAppleId":1234,
"bundleId":"afdsasd",
"bundleVersion":"bundleVersion",
"environment":"environment",
"signedRenewalInfo":{
"autoRenewProductId": "test tolem",
"autoRenewStatus": 1,
"expirationIntent" : 4,
"gracePeriodExpiresDate": 1636535141,
"isInBillingRetryPeriod": true,
"offerIdentifier": "test tolem",
"offerType": 1,
"originalTransactionId": "test tolem",
"priceIncreaseStatus": 1,
"productId": "test tolem",
"signedDate": 1636535141,
},
"signedTransactionInfo":{
"appAccountToken": "test tolem",
"bundleId": "sdfsasdf",
"expiresDate" : 1636535141,
"inAppOwnershipType": "test tolem",
"isUpgraded": true,
"offerIdentifier": "test tolem",
"offerType": 145,
"originalPurchaseDate": 1636535141,
"originalTransactionId": "test tolem",
"productId": "test tolem",
"purchaseDate": 1636535141,
"quantity": 145,
"revocationDate": 1636535141,
"revocationReason": 145,
"signedDate": 1636535141,
"subscriptionGroupIdentifier": "test tolem",
"transactionId": "test tolem",
"type": "test tolem",
"webOrderLineItemId": "test tolem"
}}}
Which is what I want to store into my database tables
Any help or idea is going to be greatly appriciated
For anybody possibly dealing with the same issues
this is how I handled the serialization it looked like it's working fine
from .models import TransactionV2, RenewalInfoV2,
AppStoreDecodedPayloadV2, AppStoreDataV2
from rest_framework import serializers
from jose import jwt
import base64
import io
from rest_framework.parsers import JSONParser
import json
class PayloadField(serializers.Field):
def to_internal_value(self, obj):
content = obj.split('.')[1]
jws_payload = base64.b64decode(content)
data = json.loads(jws_payload.decode())
serializer = AppStoreDecodedPayloadSerializerV2(data = data)
if serializer.is_valid():
return serializer.validated_data
class SignedTransactionInfo(serializers.Field):
def to_internal_value(self, obj):
content = obj.split('.')[1]
jws_payload = base64.b64decode(content)
data = json.loads(jws_payload.decode())
serializer = TransactionV2Serializer(data = data)
if serializer.is_valid():
return serializer.validated_data
class SignedRenewalInfoField(serializers.Field):
def to_internal_value(self, obj):
content = obj.split('.')[1]
algorithm = obj.split('.')[0]
secret = obj.split('.')[2]
jws_payload = base64.b64decode(content)
jws_payload_algo = base64.b64decode(algorithm)
algo = json.loads(jws_payload_algo.decode())
data = json.loads(jws_payload.decode())
serializer = RenewSerializer(data = data)
if serializer.is_valid():
return serializer.validated_data
class AppStoreNotificationSerializerReuturnV2(serializers.Serializer):
signedPayload = PayloadField()
def create(self, validated_data):
app_store_decoded_payload_data = validated_data.pop('signedPayload')
app_store_sub = AppStoreDecodedPayloadSerializerV2.create(app_store_decoded_payload_data)
return app_store_sub
class AppStoreDecodedPayloadDataSerializer(serializers.Serializer):
appAppleId = serializers.IntegerField()
bundleId = serializers.CharField()
bundleVersion = serializers.CharField()
environment = serializers.CharField()
signedRenewalInfo = SignedRenewalInfoField()
signedTransactionInfo = SignedTransactionInfo()
def create(**decoded_payload_data):
renewall_data = decoded_payload_data.pop('signedRenewalInfo')
transaction_data = decoded_payload_data.pop('signedTransactionInfo')
app_store_data = AppStoreDataV2.objects.create(**decoded_payload_data)
TransactionV2.objects.create(**transaction_data ,app_store_data = app_store_data)
RenewalInfoV2.objects.create(**renewall_data, app_store_data = app_store_data)
return app_store_data
class AppStoreDecodedPayloadSerializerV2(serializers.Serializer):
notificationType = serializers.CharField()
subtype = serializers.CharField()
notificationUUID = serializers.CharField()
data = AppStoreDecodedPayloadDataSerializer()
def create(app_store_decoded_payload):
app_store_decoded_payload_data = app_store_decoded_payload.pop('data')
decoded_payload = AppStoreDecodedPayloadV2.objects.create(**app_store_decoded_payload)
app_store_decoded_payload =AppStoreDecodedPayloadDataSerializer.create(**app_store_decoded_payload_data, app_store_decoded_payload = decoded_payload)
return app_store_decoded_payload
class TransactionV2Serializer(serializers.ModelSerializer):
class Meta:
fields = '__all__'
model = TransactionV2
class RenewSerializer(serializers.ModelSerializer):
class Meta:
fields = '__all__'
model = RenewalInfoV2
I'm currently following this example to get an API up and running (my code below)
from flask import Flask, request, jsonify
from flask_restful import Resource, Api
from sqlalchemy import create_engine
from json import dumps
import mysql.connector
db_connect = create_engine('mysql+pymysql://root:pass#localhost/news')
app = Flask(__name__)
api = Api(app)
class Events(Resource):
def get(self):
conn = db_connect.connect() # connect to database
query = conn.execute("select id, title, description, date, scheduled,favourite,count_audio,count_video,count_articles from events;")
result = [dict(zip(tuple (query.keys()) ,i)) for i in query.cursor]
return jsonify(result)
api.add_resource(Events, '/events') # Route_1
if __name__ == '__main__':
app.run(port='5002')
And I want to end up with a nested array, tags, and a nested object, location, as below
[{
"description": "TEST DESCRIPTION",
"id": 1,
"title": "TEST TITLE",
"date": "2020-09-02",
"scheduled":"true",
"favourite":"true",
"tags": ["celebration", "national holiday"],
"location": {
"state": {
"name": "new zealand",
"affiliation": ["United Nations"]
},
"province": "",
"urbanisation": "Wellington"
}
},
{
"description": "LONG DESCRIPTION",
"id": 2,
"title": "SECOND ENTRY",
"date": "2020-09-03",
"scheduled":"false",
"favourite":"false",
"tags": ["election", "national holiday"],
"location": {
"state": {
"name": "Brazil",
"affiliation": [""]
},
"province": "",
"urbanisation": ""
}
}]
Is something like this even possible? Do I need to rethink my API to have endpoints covering each nested object?
api.add_resource(Events, '/events')
api.add_resource(tags, '/events/tag')
api.add_resource(location, '/events/location')
Or, do I nest dictionaries as in this answer.
Yes its possible and totally valid. But I wouldn't query the database directly. I would use an ORM like SQLAlchemy, for flask use can use flask-sqlalchemy extension. The serialization can be achieved using flask-marshmallow
Use SQLAlchemy to create your models:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class EventModel(db.Model):
__tablename__ = "event"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String, nullable=True)
class LocationModel(db.Model):
__tablename__ = "location"
id = db.Column(db.Integer, primary_key=True)
province = db.Column(db.String, nullable=True)
event_id = db.Column(db.Integer, db.ForeignKey("event.id", ondelete="CASCADE"), nullable=False)
event = db.relationship("EventModel", backref=db.backref("locations", lazy=True))
Then you need serializer classes (employing flask-marshmallow) to handle the serialization:
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema, fields
from marshmallow_sqlalchemy import auto_field
class LocationSchema(SQLAlchemyAutoSchema):
class Meta:
model = LocationModel
load_instance = True
include_fk = False
id = auto_field(load_only=True)
class EventSchema(SQLAlchemyAutoSchema):
class Meta:
model = EventModel
load_instance = True
include_fk = False
id = auto_field(load_only=True)
locations = fields.Nested(LocationSchema, many=True)
And finally, you can serialize to json as follows:
db.drop_all()
db.create_all()
event = EventModel(title="Summer Show")
db.session.add(event)
db.session.commit()
location1 = LocationModel(province="Upper Austria", event_id=event.id)
db.session.add(location1)
location2 = LocationModel(province="Tirol", event_id=event.id)
db.session.add(location2)
db.session.commit()
schema = EventSchema()
result = db.session.query(EventModel).all()
print(schema.dump(result, many=True))
A complete tutorial can be found here.
I am trying to access subcategories according to parent id. When i am checking subcategories api it's showing all data with all parent id. I am unable to filter subcategories according to parent id. I am trying to get json data according to parent id.
If our parent id is 7 so i need all subcategories which one's has parent id 7. Please guide how i can do its.
models.py
class Category(models.Model):
name = models.CharField(max_length=254, unique=True)
status = models.BooleanField(default=True)
def __str__(self):
return self.name
class SubCategory(models.Model):
name = models.CharField(max_length=254, unique=True)
id_parent = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
price = models.IntegerField()
status = models.BooleanField(default=True)
def __str__(self):
return self.name
json
[
{
"id": 1,
"name": "IT Servic",
"price": 2000,
"status": true,
"id_parent": 7
},
{
"id": 2,
"name": "Web Development",
"price": 1000,
"status": true,
"id_parent": 8
},
{
"id": 3,
"name": "Digital Marketing",
"price": 3000,
"status": true,
"id_parent": 7
},
{
"id": 4,
"name": "RO Repair",
"price": 3444,
"status": true,
"id_parent": 9
}
]
serializers.py
class CategorySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Category
fields = '__all__'
class SubCategorySerializer(serializers.ModelSerializer):
class Meta:
model = SubCategory
fields = '__all__'
lookup_field = 'id_parent'
views.py*
class CategoryViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
serializer_class = CategorySerializer
def get_queryset(self):
user = self.request.user
if user.is_authenticated:
if user is not None:
if user.is_active and user.is_superuser:
return Category.objects.all()
raise PermissionDenied()
raise PermissionDenied()
raise PermissionDenied()
class SubCategoryViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
def get_queryset(self):
user = self.request.user
if user.is_authenticated:
if user is not None:
if user.is_active and user.is_superuser:
return SubCategory.objects.all()
raise PermissionDenied()
raise PermissionDenied()
raise PermissionDenied()
serializer_class = SubCategorySerializer
You should take a look at filtering.
Basically, you can either do your filtering "manually" in the get_queryset()
def get_queryset(self):
id_parent = self.request.query_params.get('id_parent')
queryset = super().get_queryset()
if id_parent:
queryset = queryset.filter(id_parent=id_parent)
return queryset
Or use a third-party library such as django-filter
you can add a custom action to your viewset like this, assuming you can set the appropriate urls/routes
#action(detail=False, methods=['GET'])
def get_sub_categories(self, request, *args, **kwargs):
category_id = self.request.query_params.get("category_id", None)
queryset = self.get_queryset()
filtered_sub_categories = queryset.filter(id_parent=category_id)
serializer = self.get_serializer(filtered_sub_categories, many=True)
return Response(serializer.data)
I have ViewSet which have SearchFilter in filter_backends and two search_fields. How to return JSON represents the only field results?
For example if i send response for search with "jo" substring i will have only one field for this search(funded user name or full name), not both user name and email in each JSON object:
{
[{
"username": "jonh";
},
{
"fullname": "Jonh";
},
{
"username": "jo";
},
{
"fullname": "Johnson";
}
]
}
viewsets.py:
class UserViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
queryset = User.objects.all()
permission_classes = (IsUserOrReadOnly,)
filter_backends = (filters.SearchFilter,)
search_fields = ('^username', '^fullname',)
def get_serializer_class(self):
if hasattr(self, 'action') and self.action == 'list':
return UserListSerializer
return UserDetailSerializer
serializers.py:
class UserListSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email', 'fullname')
I would create a Serializer factory function that takes the search params as an an argument:
def generate_user_list_serializer(search_terms):
class UserListSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = tuple(search_terms)
return UserListSerializer
Then in your view, have the serializer generated on the fly:
def get_serializer_class(self):
# make sure that the fields are available
validated_params = [p for p in self.query_params if p in Myfields]
return generate_user_list_serializer(self.query_params)
how do i serialize output of a query with select related into a json ?
When i serialize data from query with select_related, the resultant json doesn't contain related field data.
Table schema.
from django.db import models
class User(models.Model)
username = models.CharField(max_length=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.CharField(max_length=50)
class Userinfo(models.Model)
userId = models.oneToOneField(User)
userImg = models.TextField()
city = models.CharField(max_length=30)
says = models.CharField(max_length=200)
Query using select related
from django.core import serializers
json_serializer = serializers.get_serialier("json")()
uinfo = Userinfo.objects.filter(userId=1).select_related('userId')
response = json_serializer.serialize(uinfo, ensure_ascii=False, indent=2, use_natural_keys=True)
The result of the response is
[{
"pk": 1,
"model": "userinfo",
"fields": {
"city": "mycity",
"says": "Hi, its me",
"userImg": "profile_img.png",
"userId": [ "user1" ]
}
}]
while the result suppose to be
[{
"pk": 1,
"model": "userinfo",
"fields": {
"city": "mycity",
"says": "Hi, its me",
"userImg": "profile_img.png",
"userId": [{
"username" : "user1",
"first_name" : "User",
"last_name" : "ls1",
"email" : "user1#host.com"
}]
}
}]
I changed the query using values instead of select related but i go this error
uinfo = Userinfo.objects.filter(userId=1).values('userImg', 'city', 'says', 'userId__username', 'userId__first_name', 'userId__email')
response = json_serializer.serialize(uinfo, ensure_ascii=False, indent=2, use_natural_keys=True)
Error:
concrete_model = obj._meta.concrete_model
AttributeError: 'dict' object has no attribute '_meta'
I have tried some solutions found on stackoverflow too but i got errors during serializing
First method
from rest_framework.renderers import JSONRenderer
uinfo = Userinfo.objects.filter(userId=1).select_related('userId')
response = JSONRenderer().render(uinfo)
and the type() of uinfo is
<class 'django.db.models.query.QuerySet'>
Error:
TypeError: [<Userinfo: Userinfo object>] is not JSON serializable
Second method:
from rest_framework.renderers import JSONRenderer
uinfo = Userinfo.objects.filter(userId=1).values('userImg', 'city', 'says', 'userId__username', 'userId__first_name')
response = JSONRenderer().render(uinfo)
and the type() of uinfo returned is class
<'django.db.models.query.ValuesQuerySet>
Error:
TypeError: [{'userImg': u'profile_img.png', 'city': u'mycity', 'says' : u'Hi, its me' 'userId__username': u'user1', 'userId__first_name': u'user'}] is not JSON serializable
I also tried to convert query output result into a dict(using https://djangosnippets.org/snippets/2670/ ) before serializing into json but i got the following error
uinfo = Userinfo.objects.filter(userId=1).select_related('userId')
uinfodata = deep_dump_instance(uinfo)
Error:
in deep_dump_instance
if (instance.__class__, instance.pk) in seen:
AttributeError: 'QuerySet' object has no attribute 'pk'
views.py
from django.utils import simplejson
def convert_to_json():
uinfo = Userinfo.objects.filter(userId_id__in=inner_qs).values('userId__username', 'userImg', 'says', 'userId__first_name', 'city')
lusers = ValuesQuerySetToDict(users)
response = simplejson.dumps(lusers)
return response
def ValuesQuerySetToDict(vqs):
return [item for item in vqs]