I have 'average_rating' field that takes values from field 'rates' and calculate average value. But when 'rates' field is empty, its shows null. views.py:
class BooksView(viewsets.ModelViewSet):
serializer_class = BooksSerializer
queryset = BooksModel.objects.all()
filter_backends = [filters.DjangoFilterBackend, filtersrest.SearchFilter, filtersrest.OrderingFilter,]
filterset_class = Myfilter
filterset_fields = ('genres','date',)
search_fields = ['title']
def get_queryset(self):
return BooksModel.objects.all().annotate(average_rating=models.ExpressionWrapper(Round(Avg('rates__rate'), 2), output_field=models.FloatField()), _sum_users_cart=Count('users__user'))
In the output i have this:
"id": 18,
"authors": [
{
"author": "Андрей курпатов"
}
],
"age": [],
"tags": [],
"users": [],
"genres": [],
"rates": [],
"average_rating": null,
"sum_users_cart": 0,
"title": "Мозг и бизнес",
"desc": "123",
"url_photo": "https://s1.livelib.ru/boocover/1007572198/o/fde7/Andrej_Kurpatov__Mozg_i_biznes.jpeg",
"is_published": true,
"date": "Декабрь 29, 2022",
"time": "20:20:02"
And i need something like this:
"id": 18,
"authors": [
{
"author": "Андрей курпатов"
}
],
"age": [],
"tags": [],
"users": [],
"genres": [],
"rates": [],
"average_rating": 0,
"sum_users_cart": 0,
"title": "Мозг и бизнес",
"desc": "123",
"url_photo": "https://s1.livelib.ru/boocover/1007572198/o/fde7/Andrej_Kurpatov__Mozg_i_biznes.jpeg",
"is_published": true,
"date": "Декабрь 29, 2022",
"time": "20:20:02"
CodePudding user response:
You may try to do it like this:
from django.db.models import Case, When, FloatField
return BooksModel.objects.all().annotate(
average_rating=Case(
When(rates__isnull=True, then=0),
default=Round(Avg('rates__rate'), 2),
output_field=FloatField()
),
_sum_users_cart=Count('users__user')
)
CodePudding user response:
you can add a default value for the average_rating
in your models.py
for example:
from django.db import models
class BooksModel(models.Model):
...
average_rating = models.DecimalField(max_digits=12, decimal_places=2, default=0, null=False)
...
by doing that you ensure that whenever the value of average_rating
is not set it will always be set to 0 instead of None
.