From 7aa9c49015872b11af7fd721e97bc56d284c3d30 Mon Sep 17 00:00:00 2001 From: Yirou Qiu <y2qiu@uwaterloo.ca> Date: Thu, 9 Mar 2023 09:34:31 -0500 Subject: [PATCH] add search view. version0.1 --- core/api/bill.py | 16 ++++++------ core/api/billSearch.py | 39 +++++++++++++++++++++++++++++ core/models/bill.py | 56 ++++++++++++++++++++++++++++++++++++++++++ core/urls.py | 6 ++++- requirements.txt | 1 + 5 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 core/api/billSearch.py diff --git a/core/api/bill.py b/core/api/bill.py index 661a1dd..184dc1e 100644 --- a/core/api/bill.py +++ b/core/api/bill.py @@ -8,10 +8,10 @@ from rest_framework import permissions, authentication class BillListCreate(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Bill.objects.all() serializer_class = BillSerializer - authentication_classes = [ - authentication.SessionAuthentication, - authentication.TokenAuthentication - ] + # authentication_classes = [ + # authentication.SessionAuthentication, + # authentication.TokenAuthentication + # ] permission_classes = (permissions.IsAuthenticated,) def get(self, request, *args, **kwargs): @@ -50,10 +50,10 @@ class BillDetail(mixins.RetrieveModelMixin, generics.GenericAPIView): queryset = Bill.objects.all() serializer_class = BillSerializer - authentication_classes = [ - authentication.SessionAuthentication, - authentication.TokenAuthentication - ] + # authentication_classes = [ + # authentication.SessionAuthentication, + # authentication.TokenAuthentication + # ] permission_classes = (permissions.IsAuthenticated,) lookup_field = "pk" diff --git a/core/api/billSearch.py b/core/api/billSearch.py new file mode 100644 index 0000000..f35d1e8 --- /dev/null +++ b/core/api/billSearch.py @@ -0,0 +1,39 @@ +from rest_framework import generics +from core.models.bill import Bill, BillSearchQuerySet +from core.serializers.bill import BillSerializer +from rest_framework import authentication + +class SearchBillListView(generics.ListAPIView): + queryset = Bill.objects.all() + serializer_class = BillSerializer + authentication_classes = [ + authentication.SessionAuthentication, + authentication.TokenAuthentication + ] + + # item = categories -----> keyword = 1/2/3/4/5 .. + # price -----> keyword = price + # date -----> keyword = month / day + # title -----> keyword = title + + def get_queryset(self, *args, **kwargs): + qs = BillSearchQuerySet(Bill) + item = self.request.GET.get("item") + result = Bill.objects.none() + user = None + if self.request.user.is_authenticated: + user = self.request.user + keyword = self.request.GET.get("keyword") + if item == "categories": + result = qs.searchCategories(keyword, user=user) + elif item == "price": + result = qs.searchPrice(keyword, user=user) + elif item == "date": + if keyword == "month": + result = qs.searchThisMonth(user=user) + elif keyword == "today": + result = qs.searchToday(user=user) + elif item == "title": + result = qs.searchTitle(keyword, user=user) + print(result) + return result \ No newline at end of file diff --git a/core/models/bill.py b/core/models/bill.py index f26e86b..349bafa 100644 --- a/core/models/bill.py +++ b/core/models/bill.py @@ -1,10 +1,66 @@ from django.db import models from django.utils import timezone from django.contrib.auth.models import User +from django.db.models import Q from core.models.utils import UUIDModel import datetime +from datetime import date +from dateutil.relativedelta import relativedelta +# pip install python-dateutil +class BillSearchQuerySet(models.QuerySet): + def searchCategories(self, query, user=None): + lookup = Q(categories = query) + qs = self.filter(lookup) + if user is not None: + qs = self.filter(user=user).filter(lookup) + return qs + + def searchPrice(self, query, user=None): + lookup = Q(price=query) + qs = self.filter(lookup) + if user is not None: + qs = self.filter(user=user).filter(lookup) + return qs + + def searchThisMonth(self, user=None): + end_date = date.today() + start_date = end_date + relativedelta(months=-1) + lookup = Q(date__range = [start_date, end_date]) + qs = self.filter(lookup) + if user is not None: + qs = self.filter(user=user).filter(lookup) + return qs + + def searchToday(self, user=None): + end_date = date.today() + start_date = end_date + relativedelta(days=-1) + lookup = Q(date__range = [start_date, end_date]) + qs = self.filter(lookup) + if user is not None: + qs = self.filter(user=user).filter(lookup) + return qs + + def searchTitle(self, keyword, user=None): + lookup = Q(title__contains = keyword) + qs = self.filter(lookup) + if user is not None: + qs = self.filter(user=user).filter(lookup) + return qs + + + # def categorieAmount(self, date, categories, user=None): + # if date == "day": + # qs = self.searchCategories(categories, user=user).searchToday(user=user) + # elif date == "month": + # qs = self.searchCategories(categories, user=user).searchThisMonth(user=user) + +class BillManager(models.Manager): + + def get_queryset(self, *args, **kwargs): + return BillSearchQuerySet(self.model, using = self._db) + class Bill(UUIDModel): user = models.ForeignKey(User, default=1, null=True, on_delete=models.SET_NULL) diff --git a/core/urls.py b/core/urls.py index f515f05..41f46c9 100644 --- a/core/urls.py +++ b/core/urls.py @@ -7,6 +7,7 @@ from core.api.password import ChangePasswordView from core.api.profile import ProfileViewSet from core.api.coupon import CouponViewSet from core.api.bill import * +from core.api.billSearch import SearchBillListView router = routers.DefaultRouter() @@ -32,5 +33,8 @@ urlpatterns += [ # bill path('api/bill/', bill_list_create_api, name="bill-list"), - path('api/bill/<uuid:pk>/', bill_detail_api, name="bill-detail") + path('api/bill/<uuid:pk>/', bill_detail_api, name="bill-detail"), + + # bill search + path('api/bill/search/', SearchBillListView.as_view(), name="bill-search") ] diff --git a/requirements.txt b/requirements.txt index faa0622..6a627f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ djangorestframework==3.14.0 knox==0.1.14 PyJWT==2.6.0 requests==2.28.2 +python-dateutil \ No newline at end of file -- GitLab