How to Updating JSONField in Django? - python-3.x

I'll give coffee to the person who found the solution Help me please. Query object:The result I want is just to update the value of auth_token
My model:
class Student(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
age = models.IntegerField(null=True, blank=True)
configuration=models.JSONField(null=True)
def __str__(self):
return self.name
Query object:The result I want is just to update the value of auth_token
class Bank:
def example(self):
query = Student.objects.get(id=1)
el =query.configuration
encoded_hand = json.dumps(el)
jsonObject = json.loads(encoded_hand)
for value in jsonObject:
checkValue=value['name']
if checkValue == 'Auth_token':
backUrl= value['value']
backUrl = "token"
query.configuration = backUrl # This is not working properly. Bad idea
query.save()
print("Ene bol:{}".format(backUrl))
MyJson :
[
{
"name": "Auth_token",
"value": "sfsdf"
},
{
"name": "Refresh_token",
"value": "sdfsdfs" # How to update this value token ?
},
{
"name": "BaseUrl",
"value": "test"
}
]

Related

Nested serializer representation for PrimaryKeyRelatedField

I want to add and remove products to an order by only using their ids, but I want the order representation to look like a nested serializer.
My Models:
class Product(models.Model):
title = models.CharField(max_length=200)
price = models.DecimalField(max_digits=1_000, decimal_places=2)
def __str__(self):
return self.title
class Order(models.Model):
date = models.DateField()
products = models.ManyToManyField(Product, blank=True, related_name='orders')
My Serializers:
class ProductSerializer(serializers.ModelSerializer):
price = serializers.DecimalField(max_digits=1_000,
decimal_places=2,
coerce_to_string=False)
class Meta:
model = Product
fields = ['id', 'title', 'price']
class OrderSerializer(serializers.ModelSerializer):
products = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all(), many=True)
class Meta:
model = Order
fields = ['id', 'date', 'products']
I'm trying to get the below representation:
{
"id": 1,
"date": "2021-08-12",
"products": [
{
"id": 1,
"title": "Item 1",
"price": 19.99
},
{
"id": 3,
"title": "Item 3",
"price": 49.99
}
]
}
However, if I want to create the above order the json should look like this:
{
"date": "2021-08-12",
"products":[1, 3]
}
And if I want to add a product with id==2 to the above order it should look like this:
{
"id": 1,
"date": "2021-08-12",
"products":[1, 3, 2]
}
I've tried overriding the to_representation() method and adding a nested serializer there, but I have no idea how to go about it. Should it look something like this, or am I going in a completely wrong direction here?
def to_representation(self, instance):
data = super().to_representation(instance)
data['products'] = ProductSerializer(data=instance['products'])
return data
Ended up fixing it with the to_representation() method. I don't know if this is the best way to do it, but it works for now.
def to_representation(self, instance):
data = super().to_representation(instance)
products_list = []
for product_id in data['products']:
product = instance.products.get(pk=product_id)
products_list.append(
{
'id': product.id,
'title': product.title,
'price': product.price
}
)
data['products'] = products_list
return data
use Nested Serializer Relationships.
and your OrderSerializer serializer class will be like this:
class OrderSerializer(serializers.ModelSerializer):
products = ProductSerializer(many=True)
class Meta:
model = Order
fields = ['id', 'date', 'products']

Has an invalid foreign key Django TestCase

i have a model pruchase and a model transaction, transactions have a ForeignKey from pruchase and when a try run the tests success th first test_payment_request but the second test_payment_transaction_state faile an launch the next error:
django.db.utils.IntegrityError: The row in table 'transactions_transactionmodel' with primary key '0664aefce71447699d8ca9e7677ba4cc' has an invalid foreign key: transactions_transactionmodel.purchase_id contains a value 'ba7dc5ac0e1c4b9eb009e772f405f5db' that does not have a corresponding value in purchases_purchasemodel.id.
this is my test:
import datetime
import socket
from django.test import TestCase
from .payment import PaymentTransactions
from apps.purchases.models import PurchaseModel
class PaymentTransactionsTestCase(TestCase):
def setUp(self):
self.purchase = {"purchase":PurchaseModel( total_value = 124236,
products = [
{
"name": "Aretes",
"value": "6490"
},
{
"name": "Manilla",
"value": "6.000"
}
],
purchase_date = datetime.datetime.utcnow()
),
"value":124236,
"client_ip": socket.gethostbyname(socket.gethostname())
}
def test_payment_request(self):
error, payment, transaction = PaymentTransactions().\
payment_transaction_request(**self.purchase)
self.assertFalse(error)
self.assertTrue(payment)
self.assertIn("tpaga_payment_url", payment)
self.assertIn("token", payment)
self.assertEquals(transaction.token, payment["token"])
print("paso prueba 1")
def test_payment_transaction_state(self):
purchase = {"purchase":PurchaseModel( total_value = 124236,
products = [
{
"name": "Aretes",
"value": "6490"
},
{
"name": "Manilla",
"value": "6.000"
}
],
purchase_date = datetime.datetime.utcnow()
),
"value":124236,
"client_ip": socket.gethostbyname(socket.gethostname())
}
error, payment, transaction = PaymentTransactions().\
payment_transaction_request(**purchase)
self.assertFalse(error)
error, transaction_created = PaymentTransactions().\
payment_transaction_state(transaction.id)
self.assertFalse(error)
self.assertEquals(transaction_created.state, transaction.state)
but i don't know whatshappends if someone know, please can explain me.
Make change models.SOMETHING to models.CASCADE in your field of Model Payment.

Flask API - create nested json response group by field single table

I have a basic API setup to do a basic Post and Get from a single table. I want to create a nested array though grouping by force_element_type
model.py
from db import db
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import text as sa_text
class ForceElementModel(db.Model):
__tablename__ = 'force_element'
__table_args__ = {'schema': 'force_element'}
force_element_id = db.Column(UUID(as_uuid=True), primary_key=True, server_default=sa_text("uuid_generate_v4()"))
name = db.Column(db.String(100), nullable=False)
force_element_type = db.Column(db.String(20), nullable=False)
def __init__(self, name, force_element_type):
self.name = name
self.force_element_type = force_element_type
def json(self):
return {'name': self.name, 'force_element_type': self.force_element_type}
#classmethod
def find_by_name(cls, name):
return cls.query.filter_by(name=name).first() # simple TOP 1 select
def save_to_db(self): # Upserting data
db.session.add(self)
db.session.commit() # Balla
def delete_from_db(self):
db.session.delete(self)
db.session.commit()
resource.py
from flask_restful import Resource, reqparse
#from flask_jwt import jwt_required
from models.force_element import ForceElementModel
class ForceElement(Resource):
parser = reqparse.RequestParser() # only allow price changes, no name changes allowed
parser.add_argument('force_element_type', type=str, required=True, help='This field cannot be left blank')
##jwt_required()
def post(self, name):
if ForceElementModel.find_by_name(name):
return {'message': "An Force Element with name '{}' already exists.".format(name)}, 400
data = ForceElement.parser.parse_args()
force_element = ForceElementModel(name, data['force_element_type'])
try:
force_element.save_to_db()
except:
return {"message": "An error occurred inserting the item."}, 500
return force_element.json(), 201
class ForceElementList(Resource):
##jwt_required()
def get(self):
return {'force_elements': [force_element.json() for force_element in ForceElementModel.query.all()]}
class ForceElementType(Resource):
##jwt_required()
def get(self):
The GET endpoint using ForceElementList returns
{
"force_elements": [
{
"name": "San Antonio",
"force_element_type": "ship"
},
{
"name": "Nimitz",
"force_element_type": "ship"
},
{
"name": "Nimitz- Starboard",
"force_element_type": "Crew"
},
{
"name": "Nimitz- Port",
"force_element_type": "Crew"
}
]
}
I don't know how to group by force_element_type and return
[
"ship": [
{
"name": "San Antonio",
"force_element_id": "xxx1"
},
{
"name": "Nimitz",
"force_element_id": "xxx2"
}],
"crew": [
{
"name": "Nimitz- Starboard",
"force_element_id": "yyy1"
},
{
"name": "Nimitz- Port",
"force_element_id": "yyy2"
}
]
]
How do I create this separate andpoint?
OK I got there, here is how I did it. Is there a better way?
Lesson one use an online parser to check the json format this is what I was actually aiming for and the square braket at then start had me scratching my head for a while
{
"ship": [
{
"name": "San Antonio",
"force_element_id": "xxx1"
},
{
"name": "Nimitz",
"force_element_id": "xxx2"
}],
"crew": [
{
"name": "Nimitz- Starboard",
"force_element_id": "yyy1"
},
{
"name": "Nimitz- Port",
"force_element_id": "yyy2"
}]
}
This code creates the correct format for the output
class ForceElementType(Resource):
##jwt_required()
def get(self):
types = {}
force_elements = ForceElementModel.query.order_by(ForceElementModel.force_element_type.desc()).all()
for force_element in force_elements:
nested = {'name': force_element.name, 'force_element_id': str(force_element.force_element_id)}
print(nested)
if not force_element.force_element_type in types:
types[force_element.force_element_type] = []
types[force_element.force_element_type].append(nested)
response = types

Not able to pass last inserted_id from parent serializer to children serializer with Django restframework

I am trying to save parent (VisVisits) and children (VisVistiData) table with same api call. Data is coming into json format. I am able to save both the table except one column visit_id in the children (VisVisitData) table. visit_id does not come from the json. It is auto number type field in parent table(VisVisits) and I want to take visit_id from parent(after gets insert) table and save it to their children ids with other column in children table (VisVisitData)
I really need help to fix this issue.
Serializer
class VisVisitsSerializer(serializers.ModelSerializer):
data = VisVisitDataSerializer(many=True)
class Meta:
model = VisVisits
fields = ('visit_id','user','data')
read_only_fields = ['visit_id']
def create(self, validated_data):
visits_data = validated_data.pop('data')
visit = VisVisits.objects.create(**validated_data)
for visit_data in visits_data:
VisVisitData.objects.create(visit_id=visit.visit_id, **visit_data)
return visit
class VisVisitDataSerializer(serializers.ModelSerializer):
class Meta:
model = VisVisitData
fields = ('__all__')
model
class VisVisits(models.Model):
visit_id = models.IntegerField(primary_key=True,auto_created=True)
user = models.ForeignKey(UsrUsers, models.DO_NOTHING, blank=False, null=False)
def __str__(self):
return str(self.visit_id)
class VisVisitData(models.Model):
vdata_id = models.IntegerField(primary_key=True,auto_created=True)
visit = models.ForeignKey('VisVisits', models.DO_NOTHING, blank=True, null=True, related_name='data')
def __str__(self):
return str(self.vdata_id)
json
{
"user": "1",
"visits": [
{
"action": "i",
"local_id": "170",
"data": [
{
"Active": "1",
"LocalID": "1905",
"VisitDataID": "",
},
{
"Active": "1",
"LocalID": "1906",
"VisitDataID": "",
},
{
"Active": "1",
"LocalID": "1907",
"VisitDataID": "",
},
{
"Active": "1",
"LocalID": "1908",
"VisitDataID": "",
},
{
"Active": "1",
"LocalID": "1909",
"VisitDataID": "",
}
]
}

flask-marshmallow custom fields

I use flask-marshmallow and mongoengine.
Also flask-restplus for my API server.
Here is my api.py
class BoardSchema(ma.Schema):
class Meta:
fields = ('no', 'title', 'body', 'tags', 'created_at', 'views')
board_schema = BoardSchema()
boards_schema = BoardSchema(many=True)
class ArticleList(Resource):
def get(self):
articles = Board.objects.all()
return boards_schema.jsonify(articles)
model.py
from datetime import datetime
from mongoengine import *
from config import DB_NAME
connect(DB_NAME)
class Board(Document):
d = datetime.now()
date = "{}-{}-{}".format(d.year, d.month, d.day)
no = SequenceField()
title = StringField(required=True)
body = StringField(required=True)
tags = ListField(StringField())
likes = ListField(StringField())
views = ListField(StringField())
password = StringField(required=True)
created_at = DateTimeField(default=date)
updated_at = DateTimeField(default=date)
When I access to /article, it's result like this ->
{
"body": "123",
"created_at": "2018-08-20T00:00:00+00:00",
"no": 1,
"tags": [
"MySQL",
"C"
],
"title": "\ud14c\uc2a4\ud2b8",
"views": [
"127.0.0.1"
]
}
in "views", ip will be added who read article.
But I want to count of all the list of views and include it to my result.
The result I wanted is here.
{
"body": "123",
"created_at": "2018-08-20T00:00:00+00:00",
"no": 1,
"tags": [
"MySQL",
"C"
],
"title": "\ud14c\uc2a4\ud2b8",
"views": 20
}
I'm new at flask-marshmallow so I'm so confused how can I solve this issue.
Thanks.
Maybe you can try like this:
class BoardSchemaCustom(ma.ModelSchema):
class Meta:
model = Board
views = ma.fields.method(deserialize="_custom_serializer")
def _custom_serializer(self, obj):
return len(obj.views)
Create instance of your custom schema:
custom_board_schema = BoardSchemaCustom()
and dump it:
dump, errors = custom_board_schema.schema.dump(Board.query.first())
>>> dump
i've got the same problem. and my code works after installing marshmallow-sqlalchemy
pip install marshmallow-sqlalchemy
see from offical documentation
https://flask-marshmallow.readthedocs.io/en/latest/
Below snippet would also work:
class BoardSchemaCustom(ma.ModelSchema):
class Meta:
model = Board
views = ma.fields.Function(lambda obj: len(obj.views))

Resources