Django,how to filter multiple JSONField data? - json

Im using django with postgres i was able to add multiple filters in my views but mu question here is is there any possibility that i can filter multiple same jsonfield with different values:
ex i can filter localhost:127.0.0.1:products?areaOfUse=residential
so is there any possibilty that i can get the result of /products?areaOfUse=residential&areaOfUse=test
So from here i need to query two different json objects.
-Here are my views
class SubcategoriesProductsAPI(APIView):
# #cache_control(must_revalidate=True, max_age=3600)
def get (self, request, subCategoryId = None, pk = None):
try:
filters = {}
design = self.request.query_params.get('design', None)
dimension = self.request.query_params.get('dimension', None)
collectionName = self.request.query_params.get('collectionName', None)
material = self.request.query_params.get('material',None)
min_price = self.request.query_params.get('min_price',None)
max_price = self.request.query_params.get('max_price',None)
page = self.request.query_params.get('page', None)
wearLayer = self.request.query_params.get('wearLayer',None)
areaOfUse = self.request.query_params.getlist('areaOfUse',None)
productType = self.request.query_params.get('type', None)
installationMethod = self.request.query_params.get('installationMethod',None)
format_type = self.request.query_params.get('format_type',None)
wearLayer = self.request.query_params.get('wearLayer',None)
levelOfUse = self.request.query_params.get('levelOfUse',None)
if design is not None:
filters['product_options__options__data__design'] = design
if productType is not None:
filters['product_options__options__data__type'] = productType
if dimension is not None:
filters['product_options__options__data__dimensions__contains'] = [{'dimension': dimension}]
if collectionName is not None:
filters['product_options__options__data__collectionName'] = collectionName
if material is not None:
filters['product_options__options__data__material'] = material
if wearLayer is not None:
filters['product_options__options__data__wearLayer'] = wearLayer
if installationMethod is not None:
filters['product_options__options__data__installationMethod'] =installationMethod
if format_type is not None:
filters['product_options__options__data__format'] = format_type
if areaOfUse is not None:
filters['product_options__options__data__areaOfUse__contains'] = areaOfUse
if levelOfUse is not None:
filters['product_options__options__data__levelOfUse'] = levelOfUse
if min_price and max_price:
filters['product_options__options__data__dimensions__range__price'] = float(min_price)
filters['product_options__options__data__dimensions__0__price__lte'] = float(max_price)
queryset = Products.objects.filter(sub_categories_id = subCategoryId, is_active = True).select_related().filter(**filters)
if not queryset:
return JsonResponse({ 'status': False, 'msg': 'No products found', 'data': {} }, status=400)
if page is not None:
paginator = PageNumberPagination()
page = paginator.paginate_queryset(queryset, request)
if page is not None:
serializer = ProductSerializer(page, many=True)
return JsonResponse({ 'status': True, 'msg': 'Succesfully retrived products ', 'data': serializer.data, 'count': paginator.page.paginator.count, 'previous':paginator.get_previous_link(), 'next':paginator.get_next_link() }, status=200)
serializer = ProductSerializer(queryset, many=True)
return JsonResponse({ 'status': True, 'msg': 'Succesfully retrived products ', 'data': serializer.data }, status=200)
except Products.DoesNotExist:
return JsonResponse({ 'status': False, 'msg': 'Internal system error', 'data': {}}, status=500)

areaOfUse = self.request.query_params.getlist('areaOfUse[]',None)
/products?areaOfUse%5B%5D=residential&areaOfUse%5B%5D=test
import operator
from django.db.models import Q
from functools import reduce
queryset = Products.objects.filter(sub_categories_id = subCategoryId, is_active = True).select_related().filter(**filters)
if areaOfUse:
queryset.filter(
reduce(
operator.and_,
(Q(product_options__options__data__areaOfUse__contains=x) for x in areaOfUse)
)
)

Related

fastapi + sqlalchemy + pydantic → how to process relations

Using FastAPI I can't fetch all the data. For example I have this output :
Response body Download (but the items list is always empty):
[
{
"email": "mmm#gmail.com",
"id": 1,
"is_active": true,
"items": []
},
{
"email": "ee#gmail.com",
"id": 2,
"is_active": true,
"items": []
},
]
Endpoint are for example:
#app.get("/users/", response_model=list[schemas.User])
async def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
#app.get("/users/{user_id}", response_model=schemas.User)
async def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
I have the following schemas (database is PostgreSQL):
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str | None = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
Database is postgresql
Models are (table users and table items):
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
__table_args__ = {'schema': 'socialcampaigns'}
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items_rel = relationship("Item", back_populates="owner_id_rel")
class Item(Base):
__tablename__ = "items"
__table_args__ = {'schema': 'socialcampaigns'}
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
owner = Column(Integer, ForeignKey("socialcampaigns.users.id"))
owner_id_rel = relationship("User", back_populates="items_rel")
Crud code is:
from sqlalchemy.orm import Session
from . import models, schemas
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_users (db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
How to solve it? How do I view the list of Items when viewing users?

Karate: How to create a json object/map from 2 arrays and merge them?

I am having 2 arrays
array1 = ['a','b']
array2 = [1,2]
I want to merge these 2 arrays and convert them to map like below:
[
{
"firstparam": 'a'
"secondparam": 1
},
{
"firstparam": 'b'
"secondparam": 2
}
]
I am trying this code:
* def map1 = array1
* def map1 = karate.mapWithKey(map1, 'firstparam')
* def map2 = array2
* def map2 = karate.mapWithKey(map2, 'secondparam')
this code is creating map1 & map2. now I want to merge these 2 maps in the above format. how to do it?
basically, i want to send this map to a feature file which is expected 2 parameters.
* def result = karate.call('*.feature', map)
'*.feature' is expecting 2 parameters per call i.e, firstparam & secondparam
Here you go:
* def array1 = ['a', 'b']
* def array2 = [1, 2]
* def array3 = array1.map((x, i) => ({ firstparam: x, secondparam: array2[i] }))
* match array3 == [{ firstparam: 'a', secondparam: 1 }, { firstparam: 'b', secondparam: 2 }]

Server side pagination in Graphql Scala

I need to do server side pagination in graphql in scala. I have seven reports and have used one graphql query with different operations to get the data. Now I need to add server side pagination to it and I am not able to do that. Any help would be appreciated. Below are my code:
Schema:
val PanelNominationStatusReportDataType = ObjectType(
"PanelNominationStatus",
"Dashboard Reports",
fields[Unit, PanelRewardSatusDetail](
Field("awardName", OptionType(StringType), resolve = _.value.awardName),
Field("nominatorEmail", OptionType(StringType), resolve = _.value.nominatorEmail),
Field("nomineeEmail", OptionType(StringType), resolve = _.value.nomineeEmail),
Field("nomineeLocation", OptionType(StringType), resolve = _.value.nomineeLocation),
Field("approverEmail", OptionType(StringType), resolve = _.value.approverEmail),
Field("citation", OptionType(StringType), resolve = _.value.citation),
Field("businessJustification", OptionType(StringType), resolve = _.value.businessJustification),
Field("rating", OptionType(IntType), resolve = _.value.rating),
Field("votingStatus", OptionType(StringType), resolve = _.value.votingStatus),
Field("nominatedDate", OptionType(StringType), resolve = _.value.nominatedDate),
Field("approvedDate", OptionType(StringType), resolve = _.value.approvedDate)
)
)
Graphql Query:
Field(
"PanelNominationStatus",
ListType(PanelNominationStatusReportDataType),
description = Some("Returns the Employee Reward Report Data"),
arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
resolve = { c =>
c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
})
DataRepo:
def getPanelStatusReport(companyId: Int, startDate: Long, endDate: Long, rewardNames: Seq[String]): List[PanelRewardSatusDetail] = {
val redemptionReport = Await.result(reportsModel.findPanelRewardStatusDetailsReport(companyId, rewardNames, startDate, endDate), 20.seconds).toList
redemptionReport
}
And at last the model:
def findPanelRewardStatusDetailsReport(companyId: Int, rewardNames: Seq[String], startDate: Long, endDate: Long): Future[Seq[PanelRewardSatusDetail]] = {
val df = new SimpleDateFormat("dd-MM-yyyy")
val start = stringToDateTime(df.format(startDate * 1000L), None).toDateTime()
val end = stringToDateTime(df.format(endDate * 1000L), None).toDateTime()
val rewardFilter = if(rewardNames.nonEmpty) "AND vrrc.reward_name IN (" + rewardNames.map(a => "'" + a + "'").mkString(",") + ")" else ""
implicit val getOrdersResult = GetResult(r => PanelRewardSatusDetail(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<))
val q = sql"""select vrrc.reward_name, (select login from users where id=vrur.sender_id), (select login from users where id=vrur.receiver_ids), (select city_name from cities where id=(select city_id from users where id=vrur.receiver_ids)), (select login from users where id=approver_user_id), vrur.comment, vrur.business_justification, vrpa.rating, CASE WHEN vrpa.is_approved = 1 THEN 'VOTED' ELSE 'NOT VOTED' END, date(vrpa.created_at), date(vrpa.approved_at) from vr_panel_approval vrpa inner join vr_user_reward vrur on vrur.id=vrpa.user_reward_id inner join vr_reward_config vrrc on vrrc.id=vrur.reward_config_id where vrrc.company_id = $companyId and date(vrpa.created_at) between date($start) and date($end) #$rewardFilter"""
db.run(q.as[PanelRewardSatusDetail])
}
My request query:
{
"query": "query PanelNominationStatus($startDate: Long!, $endDate: Long!, $companyId: Int!, $rewardNames: [String!]!) { PanelNominationStatus( startDate: $startDate, endDate: $endDate, companyId: $companyId, rewardNames: $rewardNames ) { awardName nominatorEmail nomineeEmail nomineeLocation approverEmail citation businessJustification rating votingStatus nominatedDate approvedDate }}",
"operationName": "PanelNominationStatus",
"variables": {
"startDate": 1285891200,
"endDate": 1576108800,
"companyId": 355,
"rewardNames": ["PANEL AWARD FEBRUARY", "PANEL AWARD MARCH"]
}
}
I can make it possible using limit in the query and accepting it in the query but I need to send the total count of rows in the response as well. But I am not able to figure out where to make change in schema.
You just need to define another GraphQL type for your result which also contains the count,
val PanelNominationStatusResultType = ObjectType(
"PanelNominationStatusResult",
"Dashboard Reports",
fields[Unit, List[PanelRewardSatusDetail]](
Field(
"count",
IntType,
description = Some("count of nomination-status-reports in this response"),
resolve = _.value.length
),
Field(
"panelNominationStatusList",
ListType(PanelNominationStatusReportDataType),
description = Some("list of nomination-status-reports"),
resolve = _.value
)
)
)
Now, as for your query,
Field(
"panelNominationStatusResult",
PanelNominationStatusResultType,
description = Some("Returns the details of ............"),
arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
resolve = { c =>
c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
}
)
If you want the totalCount, then first of all you need to change your getPanelStatusReport method to also return the totalCount
def findPanelRewardStatusDetailsReport(
companyId: Int,
rewardNames: Seq[String],
startDate: Long,
endDate: Long
): Future[(Int, Seq[PanelRewardSatusDetail])] = ???
// updated result type
val PanelNominationStatusResultType = ObjectType(
"PanelNominationStatusResult",
"Dashboard Reports",
fields[Unit, (Int, List[PanelRewardSatusDetail])](
Field(
"totalCount",
IntType,
description = Some("total count of nomination-status-reports"),
resolve = _.value._1
),
Field(
"count",
IntType,
description = Some("count of nomination-status-reports in this response"),
resolve = _.value._2.length
),
Field(
"panelNominationStatusList",
ListType(PanelNominationStatusReportDataType),
description = Some("list of nomination-status-reports"),
resolve = _.value._2
)
)
)

python csv writing SET values

Python 3.6
I am trying to write set values to CSV , I am getting the following output for the given code.
import csv
class test_write:
#classmethod
def test_write1(cls):
fieldnames1 = ['first_name', 'last_name']
cls.write_a_test1(fieldnames=fieldnames1)
#classmethod
def write_a_test1(cls, fieldnames):
with open('/Users/Desktop/delete1.csv', 'w') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
abc = cls.var1()
writer.writerow(abc)
print("Done writing")
#staticmethod
def var1():
d = ('my', 'name', 'is', 'hahaha')
c = set()
abc = {'first_name': c, 'last_name': d}
return abc
test_write.test_write1()
When I open CSV file:
Output:
first_name last_name
set() ('my', 'name', 'is', 'hahaha')
I don't want it to print set() in the file if it is empty. Instead I need blank. Variable 'C' might have or might not have values it depends. How do I proceed with that.
Dictwriter expects the keys and values to be strings, so str is being called on the objects. What you should use is something like:
d = ('my', 'name', 'is', 'hahaha')
c = set()
abc = {'first_name': ' '.join(c), 'last_name': ' '.join(d)}
return abc
The the result of the file will be:
first_name,last_name
,my name is hahaha

Getting Assertion error , when asserting json response value with datasource

I'm Asserting my Json response values with my database and but I'm getting assertion error.
Here is groovy script:
import groovy.json.JsonSlurper
// DataBase Properties
def DBcaseID = context.expand('${DataSource#CaseID}')
def DBDescription = context.expand('${DataSource#Description}' )
def row = testRunner.testCase.testSteps["DataSource"].currentRow
def CasesResponse = context.expand( '${Cases#Response}' )
def json = new JsonSlurper().parseText(CasesResponse)
//Response Values
def CaseID = json.Root[row-1].CaseID
def Description = json.Root[row-1].Description
assert CaseID == DBcaseID, "DB value: ${DBcaseID} is not equals to JSONResp value: ${CaseID}"
assert Description == DBDescription, "DB value: ${DBDescription} is not equals to JSONResp value: ${Description}"
Error log:
ERROR:An error occurred [DB value: 5 is not equals to JSONResp value: 5. Expression: (CaseID == DBcaseID). Values: CaseID = 5, DBcaseID = 5], see error log for details
ERROR:An error occurred [DB value: 4 is not equals to JSONResp value: 4. Expression: (CaseID == DBcaseID). Values: CaseID = 4, DBcaseID = 4], see error log for details
Even CaseID field values are same in database and json response