TypeError:日期类型的对象不可JSON序列化

时间:2019-02-06 15:51:52

标签: django

我试图在多个参数的基础上查询数据库,基本上我从表中获取所有记录,然后根据传递的参数将它们过滤掉。虽然搜索部分工作正常,但是当返回结果查询集时,出现以下错误:

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=&section=&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

此外,这就是我过滤记录的方式,如果有人有更好的处理方法,请分享。

2 个答案:

答案 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