我正在尝试将查询集中的数据导出到不同的文件格式,我遇到了json格式的问题。
这是我的一小段代码:
from django.core import serializers
def export_categories_json(request):
with open("categories.json", "w") as out:
data = serializers.serialize("json", Category.objects.all().values_list('id', 'name'))
out.write(data)
然后,我在模板中设置了一个调用此函数的按钮,并应下载json文件。但我有这个问题:
Traceback:
File "/home/val/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/home/val/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/home/val/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/val/Bureau/Projets/Publication/publication/src/web/views/exports.py" in export_categories_json
276. data = serializers.serialize("json", Category.objects.all().values_list('id', 'name'))
File "/home/val/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/serializers/__init__.py" in serialize
129. s.serialize(queryset, **options)
File "/home/val/.pyenv/versions/Publication3.6.2/lib/python3.6/site-packages/django/core/serializers/base.py" in serialize
84. concrete_model = obj._meta.concrete_model
Exception Type: AttributeError at /Category/json
Exception Value: 'tuple' object has no attribute '_meta'
我的代码有问题吗?我无法向json文件发送查询集?
编辑:
我写了这个并且它有效,但json显示在我的模板中。我如何将这个导出到json文件?
def export_categories_json(request):
from django.http import JsonResponse
data = list(Category.objects.values())
return JsonResponse(data, safe=False)
请不要自己进行序列化:Django有一些内置的序列化功能,你可以子类化序列化程序来改变它的行为。
您的视图也不会返回HTTP响应,但这是它应该满足的合同(它应该返回HTTP响应,否则应该引发一些错误)。
相反,您将内容写入文件,但写入文件通常不是一个好主意(除非您希望文件大小很大,在这种情况下您可以使用临时文件)。通过使用文件,您创建竞争条件,黑客也可能旨在“注入”不同的文件名,从而覆盖某些文件以运行任意代码,或更改凭据,最后服务器可能具有某些权限使其无法写入文件(目录的权限)。
Django允许您查看HTTP响应作为流对象,可以将内容写入,例如:
from django.http import HttpResponse
from django.core import serializers
def export_categories_json(request):
response = new HttpResponse(content_type='application/json')
response['Content-Disposition'] = 'attachment;filename=categories.json'
serializers.serialize(
'json',
Category.objects.all(),
fields=['name'],
stream=response
)
return response
Django的序列化适用于模型,但您使用的是.values_list()
,它返回普通的Python list
s。
在您的具体情况下,您可以简单地使用内置的json
模块:
import json
def export_categories_json(request):
with open("categories.json", "w") as out:
values = list(Category.objects.all().values_list('id', 'name'))
json.dump(values, out)
除了queryset对象之外的django序列化,
Category.objects.all().values_list('id', 'name')
这将返回元组,你可以用下面替换
data = list(Category.objects.all().values('id', 'name'))
with open("file.json", "w+") as file:
file.write(data)
如果要将某些内容的json表示写入文件,请使用json.dump
:
import json
from django.shortcuts import redirect
def export_to_json(request):
with open('export.json', 'w') as f:
json.dump(list(Category.objects.all().values_list('id', 'name')), f)
return redirect('/')