Django rest with raw - sql

sorry I have a problem with raw, I'm trying to add up the total sales for each month, but I have an error.
this is my sight.
class TotalSale(ListAPIView):
serializer_class = TotalSaleSerealizer
def get_queryset(self):
queryset = Sale.objects.raw("SELECT 1 id, SUM(totalprice),
to_char(datesale,'yyyy-MM') FROM sales_sale group by
to_char(datesale,'yyyy-MM')")
return queryset
the to_char I am using to change the format of my date and so I can calculate the sales of each month, this query works well when I do it directly in Postgresql, but when I do it in django I do not vote for the correct data.
1,'1197','2018-10'
1,'612','2018-09'
1,'1956','2018-08'
and it's fine I calculate the sum of the sales of each month
But when I do that in Django, this comes to me.
{
"id": 1,
"totalprice": 144,
"datesale": "2018-08-06"
},
{
"id": 1,
"totalprice": 144,
"datesale": "2018-08-06"
},
{
"id": 1,
"totalprice": 144,
"datesale": "2018-08-06"
}
I think the error is for the 1 id, just filter the data of the data that has id 1, my question is why that happens, how can I solve it try to remove the 1 id but another error comes out, how can I fix that problem.

I think that the rest is irrelevant, because the view is the most important, but here is the remaining code.
class TotalSaleSerealizer(ModelSerializer):
class Meta:
model = Sale
fields = ('id','totalprice', 'datesale')
class Sale(models.Model):
id_customer = models.ForeignKey(Customer, null =False, blank=False,
on_delete=models.CASCADE)
id_user = models.ForeignKey(User, null =False, blank=False,
on_delete=models.CASCADE)
datesale = models.DateField(auto_now_add=True)
totalprice = models.IntegerField()
these are the serealizer and the model

Related

DRF Serializers. Different fields on serialize and deserialize methods

What is the best approach to have the same field name in Serializer but different behaviour on serializing and deserializing data? (I want to put only group_id on input and get full related info on the output)
So I want my schema looks like this when I input my data
{
"group": 1,
"other_fields": []
...
}
But got this (This is the way i want data looks like on the output only)
{
"group": {
"name": "string",
"description": "string",
"image": "string",
"is_public": true
},
"other_fields": []
...
}
My serializer right now
class TaskSerializer(serializers.ModelSerializer):
group = GroupSerializer()
class Meta:
model = Task
fields = "__all__"
Edit: Added group serializer and my Group model. Nothing special
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
fields = "id", "owner", "name", "description", "image", "is_public"
read_only_fields = "owner",
class Group(models.Model):
name = models.CharField(max_length=32)
owner = models.ForeignKey("user.User", on_delete=models.CASCADE)
description = models.CharField(max_length=32)
image = models.ImageField(upload_to=func)
is_public = models.BooleanField(default=True)
In your TaskSerializer class you are serializing group with GroupSerializer(), which serializes the relation as an object with the fields you specified in it's implementation.
You instead want to serialize a single field, for that you could use SlugRelatedField(slug_field='id') which serializes the relation as a single field from group.
Because your Group model doesn't have a primary key field, Django generates an automatic AutoField(primary_key=True) id field, thus you can use PrimaryKeyRlatedField().
Try:
class TaskSerializer(serializers.ModelSerializer):
group = serializers.PrimaryKeyRelatedField()
class Meta:
model = Task
fields = "__all__"
For more examples, I suggest reading this tip from testdriven.io.

Eloquent SUM and GET Latest Relationship Data

I have two models User and Transaction. The User model has a one-to-Many relationship with Transaction:
I am trying to return
some data from the User table
sum of all amount in the Transaction table that belongs to the user
transaction hash from the most recent transaction
Expected response:
{
"name": "User A",
"image": "images/user-a.png",
"last_transaction_hash": "79s8s900",
"total_transaction_sum": "30000"
},
{
"name": "User B",
"image": "images/user-b.png",
"transaction_hash": "a102920",
"total_transaction_sum": "23000"
}
What I have tried:
$users = User::withCount([
'transactions as total_transaction_sum' => function ($q) {
return $q->select(DB::raw("SUM(amount) as amount"));
},
])
->orderByRaw('total_transaction_sum DESC NULLS LAST')
->get();
With the above query I can return data for (1 & 2) but I find it hard to select the specific columns that I want to see and I still can't figure out how to return transaction hash of the latest transaction (3).
you can use Query builder to achive this in sort line like this
$users = User::select(\DB::raw('user.name, user.image, SUM(transactions.amount) as total_transaction_sum'))
->join('transactions', 'users.id', '=', 'transactions.user_id')
->orderByRaw('total_transaction_sum DESC NULLS LAST')
->get()
->groupBy('id')
->map(function ($row) {
$opt = $row;
$opt['transaction_hash'] = optional($row->last())->id;
return $opt;
})->values();
ref link https://laravel.com/docs/8.x/queries#joins

Get data on basis of fields in Yii2

I am trying to get data on basis of fields in query param ie
users/1?fields=id,name
its give id and name using findOne
User::findOne(1);
Result:
{
"id": 12,
"name": 'Jhon'
}
When
users?fields=id,name
Its give all fields of user Model using findAll()
User::findAll([$ids])
Result:
[
{
'id': 1
'name': abc
'age':30
'dob':1970
'email':abc#test.com
},
{
'id': 2
'name': abc
'age':30
'dob':1970
'email':abc1#test.com
},
Why findAll() not work like findOne() result
I have read Data provider and solve the problem

Flask SQLAlchemy + Marshal_list_with + selected columns

I am trying to pull down selected columns from joining two tables and returning the results using api.marshal_list_with. My model definition is as follows:
project_model = api.model('Project', {
'id': fields.String(readOnly=True, description='Unique project id'),
'name': fields.String(required=True, description='Project name'),
'created_user_id': fields.String(description='Id for user that created the project'),
'created_time': fields.String(readOnly=True, description='Time of first creation'),
'updated_time': fields.String(description='Time of last modification'),
'access_type': fields.String(description='Level of access')})
The actual request code is:
#api.marshal_list_with(project_model)
def get(self):
"""
Get details of all projects associated with user
"""
user_id = get_jwt_identity()
projects_l = db.session.query(Project, ProjectUserJunction).join(
ProjectUserJunction).filter(ProjectUserJunction.user_id == user_id).values(
Project.id, Project.name, Project.created_user_id,
Project.created_time, Project.updated_time,
ProjectUserJunction.access_type)
return projects_l
When I make the get call though, the response I get is a bunch of nulls:
{
"id": null,
"name": null,
"created_user_id": null,
"created_time": null,
"updated_time": null,
"access_type": null
}
If I print out the contents of project_l on the server, it's not blanks, so I know that the query is not broken. It may just be something with marshaling that I am missing. How can I resolve this issue?
I guess casting qs to list, should do the trick.

Complex count based on the latest date of a month

I have a model:
class HistoricalRecord(models.Model):
history_id = models.CharField(max_length=32)
type = models.CharField(max_length=8)
history_date = models.DateField()
How can I get the count of each type of HistoricalRecord by getting only the latest object (based on the history_id) for a given month. For example:
With these example objects:
HistoricalRecord.objects.create(history_id="ABC1", type="A", history_date=date(2000, 10, 5))
HistoricalRecord.objects.create(history_id="ABC1", type="A", history_date=date(2000, 10, 27))
HistoricalRecord.objects.create(history_id="DEF1", type="A", history_date=date(2000, 10, 16))
HistoricalRecord.objects.create(history_id="ABC1", type="B", history_date=date(2000, 10, 8))
The result should be:
[
{
"type": "A",
"type_count": 2
},
{
"type": "B",
"type_count": 0
}
]
"A" is 2 because the latest HistoryRecord object with history_id "ABC1" is on the 27th and the type is A; the other one is the record with history_id "DEF1".
I've tried:
HistoricalRecord.objects.filter(history_date__range(month_start, month_end)).order_by("type").values("type").annotate(type_count=Count("type"))
but obviously this is incorrect since it gets all the values for the month. The structure of the result doesn't have to be exactly like above, as long as it clearly conveys the count of each type.
This can likely be done with .extra(), add this to the query:
.extra(
where=["""history_date = (SELECT MAX(history_date) FROM historical_record hr
WHERE hr.history_id = historical_record.history_id
AND hr.history_date < %s)"""],
params=[month_end]
)