我试图在多个参数的基础上查询数据库,基本上我从表中获取所有记录,然后根据传递的参数将它们过滤掉。虽然搜索部分工作正常,但是当返回结果查询集时,出现以下错误:
TypeError:日期类型的对象不可JSON序列化
我不确定为什么会发生这种情况,因为我没有尝试序列化任何东西。
我的代码如下:
视图
class SearchView(LoginRequiredMixin, generic.ListView):
login_url = '/login/'
template_name = 'scand/search_result.html'
context_object_name = 'images'
def get_queryset(self):
form = SearchForm(self.request.GET)
query_dict = {}
if form.is_valid():
query_dict = form.cleaned_data
self.request.session['query_dict'] = query_dict
queryset = ImageTag.objects.search(query_dict)
print(queryset)
return queryset
模型经理
class ImageTagManager(models.Manager):
def ordered_images(self):
queryset = self.model.objects.order_by('id').all()
return queryset
def search(self, query_dict):
if isinstance(query_dict, list):
queryset = ImageTag.objects.filter(id__in=query_dict)
if queryset is not None:
return queryset
else:
return False
# Initially getting all objects
queryset_initial = ImageTag.objects.all()
# copying queryset_initial to filter
queryset = queryset_initial
queryset = queryset.filter(company__iexact=query_dict['company']) if query_dict.get('company') not in (
None, '') else queryset
queryset = queryset.filter(accoff__iexact=query_dict['accoff']) if query_dict.get('accoff') not in (
None, '') else queryset
queryset = queryset.filter(section__iexact=query_dict['section']) if query_dict.get('section') not in (
None, '') else queryset
queryset = queryset.filter(docref__iexact=query_dict['docref']) if query_dict.get('docref') not in (
None, '') else queryset
start_date = query_dict.get('start_date')
end_date = query_dict.get('end_date')
if start_date not in (None, '') and end_date not in (None, '') and start_date < end_date:
queryset = queryset.filter(start_date__range=(start_date, end_date))
elif start_date not in (None, ''):
queryset = queryset.filter(start_date__exact=start_date) if query_dict.get('docref') not in (
None, '') else queryset
queryset = queryset.filter(pagenum__iexact=query_dict['pagenum']) if query_dict.get('pagenum') not in (
None, '') else queryset
queryset = queryset.filter(refnum__iexact=query_dict['refnum']) if query_dict.get('refnum') not in (
None, '') else queryset
queryset = queryset.filter(pernum__iexact=query_dict['pernum']) if query_dict.get('pernum') not in (
None, '') else queryset
queryset = queryset.filter(attr1__iexact=query_dict['attr1']) if query_dict.get('attr1') not in (
None, '') else queryset
queryset = queryset.filter(attr2__iexact=query_dict['attr2']) if query_dict.get('attr2') not in (
None, '') else queryset
queryset = queryset.filter(attr3__iexact=query_dict['attr3']) if query_dict.get('attr3') not in (
None, '') else queryset
queryset = queryset.filter(attr4__iexact=query_dict['attr4']) if query_dict.get('attr4') not in (
None, '') else queryset
queryset = queryset.filter(attr5__iexact=query_dict['attr5']) if query_dict.get('attr5') not in (
None, '') else queryset
if len(query_dict.get('tags')) > 0:
tags = query_dict['tags']
queryset = queryset.filter(tags__name__in=[tags])
if queryset != queryset_initial:
return queryset
else:
return []
错误
Internal Server Error: /search/
Traceback (most recent call last):
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\utils\deprecation.py", line 93, in __call__
response = self.process_response(request, response)
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\contrib\sessions\middleware.py", line 58, in process_response
request.session.save()
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\contrib\sessions\backends\db.py", line 83, in save
obj = self.create_model_instance(data)
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\contrib\sessions\backends\db.py", line 70, in create_model_instance
session_data=self.encode(data),
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\contrib\sessions\backends\base.py", line 96, in encode
serialized = self.serializer().dumps(session_dict)
File "C:\Users\User\PycharmProjects\scandoc\venv\lib\site-packages\django\core\signing.py", line 87, in dumps
return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\__init__.py", line 238, in dumps
**kw).encode(obj)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type date is not JSON serializable
[06/Feb/2019 16:25:20] "GET /search/?company=&accoff=§ion=&docref=&start_date_month=3&start_date_day=6&start_date_year=1983&end_date_month=10&end_date_day=6&end_date_year=2007&pagenum=&refnum=&pernum=&attr1=&attr2=&attr3=&attr4=&attr5=&tags= HTTP/1.1" 500 109487
此外,这就是我过滤记录的方式,如果有人有更好的处理方法,请分享。
答案 0 :(得分:2)
似乎正在发生序列化错误,因为您正在尝试将NOT EXISTS
存储在会话中:
DELETE
FROM Phrase
WHERE NOT EXISTS (SELECT 1 FROM PhraseSource PS WHERE PS.PhraseId = Phrase.PhraseId);
query_dict
包含不可JSON序列化的日期对象,默认情况下为Django will serialize session data using JSON。
要解决此问题,您应先将self.request.session['query_dict'] = query_dict
中的日期对象转换为可序列化JSON的内容(例如时间戳记),然后再将数据存储在会话中。
或者,您可以切换到使用PickleSerializer来存储日期对象。在query_dict
中设置SESSION_SERIALIZER
变量:
query_dict
请注意,如果您使用的是Cookie后端,则settings.py
存在一个漏洞。但是,您似乎正在使用数据库后端,因此应该不成问题。
答案 1 :(得分:0)
您的模型中有<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="col-lg-12">
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th colspan="2">Additional Expenses</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" class="value" id="additionalExpenses">0</td>
</tr>
<tr>
<td class="btn" onclick="additionalSub()">
<center>-</center>
</td>
<td class="btn" onclick="additionalAdd()">
<center>+</center>
</td>
</tr>
</tbody>
</table>
</div>
</div>
吗?
DateField
Django在视图中将数据转换为json。当TypeError: Object of type date is not JSON serializable
尝试转换json.dumps
对象时,就会引发此错误。
date
因此,您必须使用>>> datetime.date(2018, 12, 1)
>>> json.dumps(d)
Traceback (most recent call last):
File "/home/jos/Projects/sandbox/py-sand/.venv/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3267, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-11-1a41a0b88650>", line 1, in <module>
json.dumps(d)
File "/home/jos/.pyenv/versions/3.6.5/lib/python3.6/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/home/jos/.pyenv/versions/3.6.5/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/home/jos/.pyenv/versions/3.6.5/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/jos/.pyenv/versions/3.6.5/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'date' is not JSON serializable
将数据更改为json。参见django serializer。