Axi*_*xil 3 python django serialization pagination json
我正在尝试为带分页的列表创建 Django API,但出现此错误
TypeError: Object of type 'Page' is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
以下是我的 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.
Run Code Online (Sandbox Code Playgroud)
这是我的模型https://gist.github.com/axilaris/89b2ac6a7762f428ad715f4916f43967。as_dict 通知我有这个 .as_dict() 来创建我的 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)
Run Code Online (Sandbox Code Playgroud)
首先,我们.values()在员工查询集上使用,因为此调用的结果 ValuesQuerySet 可以用 解析list(employees)。在 Page 类中,它们在返回任何结果之前以这种方式评估实例中的对象列表。
最后,因为 JSON 不能序列化 Page 类,我们只需调用list(Page)返回一个列表。这是有效的,因为 Page 实现__getitem__并返回底层 object_list。
此外,您可能会发现某些数据类型会引发 JSON 序列化错误(values()将返回 DateTime 字段的 DateTime 对象)。在我的测试中,我遇到了Object of type 'datetime' is not JSON serializable. 如果发生这种情况,您需要使用不同的 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')}
Run Code Online (Sandbox Code Playgroud)
因为你有这个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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3966 次 |
| 最近记录: |