当前位置: 首页 > 面试题库 >

带分页的Django API列表-页面不可JSON序列化

益明朗
2023-03-14
问题内容

我正在尝试为带有分页的列表创建Django API,但是出现此错误

TypeError: Object of type 'Page' is not JSON serializable

以下是我的API代码:

@api_view(['POST'])
def employee_get_list_by_page(request):
    # ----- YAML below for Swagger -----
    """
    description: employee_get_list_by_page
    parameters:
      - name: token
        type: string
        required: true
        location: form       
      - name: page
        type: string
        required: true
        location: form   
      - name: page_limit
        type: string
        required: true
        location: form                   
    """
    token = request.POST['token']
    try:  
        auth_employee = AuthEmployeeSessionToken.objects.get(token=token)

    except AuthEmployeeSessionToken.DoesNotExist:   
        return Response("Invalid Token", status=status.HTTP_406_NOT_ACCEPTABLE)

    employee_list = Employee.objects.filter(company = auth_employee.employee.company.id)


    page = request.GET.get('page', request.POST['page'])
    paginator = Paginator(employee_list, request.POST['page_limit'])

    try:
        employees = paginator.page(page)
    except PageNotAnInteger:
        employees = paginator.page(request.POST['page'])
    except EmptyPage:
        employees = paginator.page(paginator.num_pages)

    return Response(employees,status=status.HTTP_200_OK) <-- passing employees probably cause this error that employees as Page is not JSON serializable.

这是我的模型https://gist.github.com/axilaris/89b2ac6a7762f428ad715f4916f43967。as_dict注意,我有这个.as_dict()来创建我的json进行响应。我将其用于单个请求,但用于列表我不确定如何完成。

  1. 具有分页支持的此列表的API如何查询?
  2. 我希望JSON仅列出所需字段的附带问题。

问题答案:

我刚刚尝试重新创建它,并且看到了几种解决方法。

首先,JSON将无法解析Page对象或该page.object_list属性基础的QuerySet 。它会说"Object of type 'Employee' is not JSON serialisable"

因此,要解决此问题,我将尝试:

employee_list = Employee.objects.filter(company = auth_employee.employee.company.id).values().order_by('id')

page = request.GET.get('page', request.POST['page'])
paginator = Paginator(employee_list, request.POST['page_limit'])

try:
    employees = paginator.page(page)
except PageNotAnInteger:
    employees = paginator.page(request.POST['page'])
except EmptyPage:
    employees = paginator.page(paginator.num_pages)

return Response(list(employees) ,status=status.HTTP_200_OK)

首先,我们.values()在雇员查询集上使用,因为此调用的结果ValuesQuerySet可以用解析list(employees)。在Page类内部,他们以这种方式评估实例内部的对象列表,然后返回任何结果。

最后,由于JSON无法序列化Page类,因此我们只需调用list(Page)返回一个列表即可。之所以__getitem__可行,是因为Page实现并返回了底层的object_list。

另外,您可能会发现某些数据类型将引发JSON序列化错误(values()将为DateTime字段返回DateTime对象)。在测试中,我遇到了一个问题Object of type 'datetime' is not JSON serializable。如果发生这种情况,则需要使用其他JSON编码器或扩展自己的JSON编码器。DjangoJSONEncoder可以在django.core.serializers.json.DjangoJSONEncoder中找到,并处理django中的日期时间,uuid,十进制和其他常见数据类型。

编辑::您提到的模型代码为:

class Employee(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employee')
    company = models.ForeignKey(Company)
    username = models.CharField(max_length=30, blank=False)
    email = models.CharField(max_length=30, blank=False)
    first_name = models.CharField(max_length=30, blank=False)
    last_name = models.CharField(max_length=30, blank=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.user.username

    def as_dict(self):

        return {"id": "%d" % self.id,
                "company": self.company.as_dict(),
                "username": self.username if self.username else "",
                "email": self.email if self.email else "",
                "first_name": self.first_name if self.first_name else "",
                "last_name": self.last_name if self.last_name else "",
                "tel":self.tel if self.tel else "",               
                "created_at":self.created_at.strftime('%Y-%m-%d %H:%M'),
                "updated_at":self.updated_at.strftime('%Y-%m-%d %H:%M')}

因为您具有这种as_dict方法,所以我们可以使用它来呈现您的员工的表示形式,而不必依赖.values()。方法如下:

employee_list = Employee.objects.filter(company = auth_employee.employee.company.id).order_by('id')

page = request.GET.get('page', request.POST['page'])
paginator = Paginator(employee_list, request.POST['page_limit'])

try:
    employees = paginator.page(page)
except PageNotAnInteger:
    employees = paginator.page(request.POST['page'])
except EmptyPage:
    employees = paginator.page(paginator.num_pages)
#  Here we map a lambda function over the queryset of Models to return the dictionary representation for each element in the list
employees_page = list(
    map(lambda employee: employee.as_dict(), list(employees))
)
return Response(employees_page ,status=status.HTTP_200_OK)


 类似资料:
  • 功能介绍 获取本APP的全部页面列表 接口 https://openapi.baidu.com/rest/2.0/mtj/svc/config/getPageList?access_token=[ACCESS_TOKEN]&aid=[APP_ID] 请求参数 参数名 参数类型 是否必须 描述 access_token string 是 用户准入token aid uint 是 应用ID page

  • 我在哪里出错了?如果我试图添加可分页对象来查询并运行代码,我将得到以下错误: 无法使用请求的结果类型[java.lang.long]为具有多个返回的查询创建TypedQuery;嵌套异常是java.lang.IllegalArgumentException:无法使用请求的结果类型[java.lang.long]为具有多个返回的查询创建TypedQuery

  • 来吧,各种CV党 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd

  • sp_sql_posts($tag,$where) 功能: 查询文章列表,不做分页 参数: $tag:查询语句(见$tag规则) $where:查询条件,(暂只支持数组),格式和thinkphp where方法一样; 返回: array 文章列表 示例: <?php $tag='cid:6;field:post_title,post_content;order:listorder asc'; $

  • 创建一些文章 首先,为了能展示我们的效果,我们先在后台创建几篇文章,例如如下: 安装分页插件 列表性质的页面一般都需要做分页处理,这个工作要是让我们自己处理是十分繁琐的,所以我们利用symfony2的扩展knp-paginator-bundle。 修改app/AppKernel.php文件,增加如下注册语句: new Knp\Bundle\PaginatorBundle\KnpPaginator

  • 我使用一个可分页对象返回一个对象,其中包含一个记录列表 对象的形式如下: 我可以通过两个不同的查询获得这两个

  • 显示WooCommerce产品列表,除了默认方式或使用WooCommerce Shortcode外,还可以使用自定义查询,利用wc_get_products()函数,本文介绍的方法可以实现带分页的WooCommerce自定义产品列表,既可以直接嵌入模板,也能做成shortcode在任何地方使用。 WooCommerce Custom Product Loop代码 下面的代码定义了一个模板标签sol

  • 问题内容: 我不太清楚如何使用ajax获取部分视图以呈现页面列表。 我最接近使用的)是来自在部分视图中使用分页的示例,asp.netmvc 我基本上是在尝试创建一个包含每个用户评论列表的页面,该页面可以按照与stackoverflow用户页面上的“答案”选项卡相同的方式进行更改。 分页在第一次单击时就可以正常工作,但是当我再次单击该分页器时,部分视图即已返回。 控制器: 观看次数: Index.c