2

I am trying to query database on the basis of multiple parameters, basically I fetch all the records from a table and then filter them out according to the parameters passed. Although the search portion works fine but when the resultant query set is returned, I get the following error:

TypeError: Object of type date is not JSON serializable

I am not sure why that happens since I'm not trying to serialize anything.

My code looks something like:

view

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

model manager

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 []

error

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

Also, this is how I am filtering the records, if someone has a better way of doing it, please share.

2 Answers 2

3

The serialization error seems to be happening because you're trying to store the query_dict in session:

self.request.session['query_dict'] = query_dict

The query_dict contains date objects which are not JSON serializable and by default Django will serialize session data using JSON.

To resolve, you should convert the date objects in the query_dict into something which is JSON serializable (e.g. a timestamp) before you store the data in session.

Alternatively you could switch to using the PickleSerializer which would allow you to store the date objects. Set the SESSION_SERIALIZER variable in your settings.py:

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

Note that there is a vulnerability with the PickleSerializer if you're using the cookie backend. However, you seem to be using the database backend so that should be less of an issue.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, this was the problem. Do you have any suggestions the way I'm filtering the queryset? Is there a better way to do it?
@Majid glad to help. Yes I think there is a way you could simplify the filtering of the queryset and reduce the amount of boilerplate. One way would be to iterate the dictionary and call query.filter() with a dynamic argument based on the current dictionary key. It would be best to raise a separate question on SO to address that.
I have posted a new question stackoverflow.com/q/54567423/6915030
0

Is there are DateField in your model?

TypeError: Object of type date is not JSON serializable

Django converts data to json in view. And This error is raied when json.dumps tried to convert date object.

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

So you must use serializer for change your data to json. See django serializer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.