Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

Django restframework加Vue打造前后端分离的网站(九)查询筛选和搜索



在前面讲后端API的文章中,已经有介绍怎么创建出get / post / put / patch / delete的方法,对应着model中的业务对象。不过在开发过程中,这些API是不够的,往往需要特定的查询、业务性质的筛选、以及搜索。

比如有一个电商网站,可以列举出所有的电脑,也可以进入某一个电脑的配置页面,在用户使用时,还需要查询在最近一年发布的产品的数量,筛选属于平板电脑的产品,搜索某一个型号的电脑,等等。在这篇文章中,会以简单的例子记录如何查询筛选搜索。

比如现在有一个computer的model

class Computer(models.Model):

    COMPUTER_TYPES = (
       ("laptop", "laptop"),
       ("tablet", "tablet"),
       ("desktop", "desktop")
    )
    name = models.CharField(max_length=100)
    computer_type = models.CharField(choices=COMPUTER_TYPES, default=COMPUTER_TYPES[0][0], max_length=100)
    cpu = models.CharField(max_length=100)
    memory = models.CharField(max_length=100)
    disk = models.CharField(max_length=100)
    main_board = models.CharField(max_length=100)
    display_card = models.CharField(max_length=100)
    monitor = models.CharField(max_length=100)
    publish_time = models.DateTimeField(default=timezone.now)
    halt_time = models.DateTimeField(blank=True)

查询

前端需要显示当前网站里售卖的电脑一共有多少,于是在view.py中新增一个查询,继承APIView(可以参考前面的文章:Django restframework加Vue打造前后端分离的网站(三)在View中自定义API)

from .models import Computer

class ComputerAmount(APIView):

    def get(self, request):
        """
        Return amount of all computers.
        """
        count = {"count": Computer.objects.count()}
        return Response(count)

在url.py中新增路由

from django.urls import path
from . import views

urlpatterns = [
    path('', views.ComputerList.as_view(), name='computer_list'),
    path(r'<int:pk>/', views.ComputerDetail.as_view(), name='computer_detail'),
    path(r'amount/', views.ComputerAmount.as_view(), name='computer_amount'),
]

此时get请求类似http://127.0.0.1:8000/automation/api/computer/amount的地址即可获取到需要的数据。

筛选

根据条件筛选往往有两种,一种是在get请求中给予筛选的字段{"type_name": "tablet"},url仍然是原url;一种是筛选的字段体现在url中,比如http://127.0.0.1:8000/automation/api/computer/tablet/. 两者只是在取参数不一致,其他几乎一样。如果继承于generics.ListAPIView则重写.get_queryset(),如果继承于APIView,则重写.get().

在view.py中新增

from .models import Computer
from .serializers import ComputerSerializer
from rest_framework import generics

class ComputerFilterInUrl(generics.ListAPIView):
    serializer_class = ComputerSerializer

    def get_queryset(self):
        """
        This view return all computers based on url parameter
        """
        type_name = self.kwargs['type_name']
        return Computer.objects.filter(computer_type=type_name)


class ComputerFilterInRequest(generics.ListAPIView):
    serializer_class = ComputerSerializer

    def get_queryset(self):
        """
        This view return all computers based on request parameter
        """
        return Computer.objects.filter(computer_type=self.request.data["type_name"])

在url.py中对这两个class新增路由

from django.urls import path
from . import views

urlpatterns = [
    ...
    path(r'in_url/<str:type_name>/', views.ComputerFilterInUrl.as_view(), name='computer_filter_in_url'),
    path(r'in_request/', views.ComputerFilterInRequest.as_view(), name='computer_filter_in_request'),
]

搜索

其实搜索也是一种筛选,只是在restframework中使用方式略有不同,便分开介绍。

简单来说,在继承于generics.ListAPIView的class中声明filter_backends和search_fields即可使用。

from .models import Computer
from .serializers import ComputerSerializer
from rest_framework import generics
from rest_framework import filters

class ComputerList(generics.ListAPIView):
    """
        get:
            Return all projects or based on search condition.
    """
    queryset = Computer.objects.all().order_by("id")
    serializer_class = ComputerSerializer
    filter_backends = [filters.SearchFilter]
    search_fields = ["name", "=computer_type"]

搜索可以部分匹配,也可以完全匹配,也可以正则匹配,官方文档是这么说的:

  • '^' Starts-with search.
  • '=' Exact matches.
  • '@' Full-text search. (Currently only supported Django's MySQL backend.)
  • '$' Regex search

上面的搜索则代表name可以部分匹配,但是搜索computer_type时则是必须完全匹配才行。比如http://127.0.0.1:8000/automation/api/computer/?search=apple则是名字里有apple都会筛选出来,http://127.0.0.1:8000/automation/api/computer/?computer_type=tabl则是computer_type是tabl才给出结果,当然这里没有写全就不会有结果返回。

另外默认的搜索参数名是search,想自定义的话则在settings.py中注明,比如

# in settings.py

REST_FRAMEWORK = {
    ...
    'SEARCH_PARAM': 's'
}

此时生效的搜索链接则是http://127.0.0.1:8000/automation/api/computer/?s=apple

下一篇:  Django通过haystack搜索文章
上一篇:  Mac上配置mysql和phpmyadmin以及问题解决

共有0条评论

添加评论

暂无评论