[Django] #31877: In Django 3.1, get_object_or_404 does not resolve SimpleLazyObjects, and throws Error binding parameter 0 - probably unsupported type from SQLite

27 views
Skip to first unread message

Django

unread,
Aug 11, 2020, 4:07:21 PM8/11/20
to django-...@googlegroups.com
#31877: In Django 3.1, get_object_or_404 does not resolve SimpleLazyObjects, and
throws Error binding parameter 0 - probably unsupported type from SQLite
-------------------------------------+-------------------------------------
Reporter: cyface | Owner: nobody
Type: Bug | Status: new
Component: Database | Version: 3.1
layer (models, ORM) |
Severity: Normal | Keywords: SQLite
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Example Code that works in 3.0, but not in 3.1:


{{{
class OfferView(TemplateView):
template_name = "offers/offer.html"

def get_context_data(self, **kwargs):
offer_slug = kwargs.get("offer_slug", "")

offer = get_object_or_404(Account, slug=offer_slug)

return {"offer": offer, "offer_slug": offer_slug}
}}}


In order to make this work in 3.1, you have to explicitly convert the
result of kwargs.get() to a string to get the SimpleLazyObject to resolve:


{{{
class OfferView(TemplateView):
template_name = "offers/offer.html"

def get_context_data(self, **kwargs):
offer_slug = kwargs.get("offer_slug", "")

offer = get_object_or_404(Account, slug=str(offer_slug))

return {"offer": offer, "offer_slug": offer_slug}
}}}


The error generated if you don't is:

**Error binding parameter 0 - probably unsupported type**

from **django/db/backends/sqlite3/operations.py**, line 144, in
_quote_params_for_last_executed_query


In both cases, the urls.py looks like:


{{{
path(
"/offers/<slug:offer_slug>/",
OfferView.as_view(),
name="offer_view",
),
}}}

When debugging, I found that offer_slug (coming in from kwargs.get) was of
type '**SimpleLazyObject**' in Django 3.1, and when I explicitly converted
it to a string, get_object_or_404 behaved as expected.

This is using Python 3.7.8 with SQLite.

--
Ticket URL: <https://code.djangoproject.com/ticket/31877>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 11, 2020, 4:22:18 PM8/11/20
to django-...@googlegroups.com
#31877: In Django 3.1, get_object_or_404 does not resolve SimpleLazyObjects, and
throws "Error binding parameter 0 - probably unsupported type" from SQLite
-------------------------------------+-------------------------------------
Reporter: cyface | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: SQLite | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:1>

Django

unread,
Aug 12, 2020, 12:58:28 AM8/12/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
---------------------------------+------------------------------------
Reporter: Tim L. White | Owner: nobody
Type: Bug | Status: new
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------------------
Changes (by felixxm):

* severity: Normal => Release blocker
* cc: Adam (Chainz) Johnson (added)
* component: Database layer (models, ORM) => Generic views
* keywords: SQLite =>
* stage: Unreviewed => Accepted


Comment:

Thanks for the report. `get_object_or_404()` and `QuerySet.filter()` with
`SimpleLazyObject` throw the same exception in Django 2.2 or 3.0.

`TemplateView.get_context_data()`'s `kwargs` returns `SimpleLazyObjects`
in Django 3.1 which causes a crash. Passing URL kwargs into context is
deprecated (see #19878) but should still work in Django 3.1 and 3.2.

Regression in 4ed534758cb6a11df9f49baddecca5a6cdda9311.
Reproduced at 60626162f76f26d32a38d18151700cb041201fb3.

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:2>

Django

unread,
Aug 12, 2020, 7:19:46 AM8/12/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: assigned

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Adam (Chainz) Johnson):

* owner: nobody => Adam (Chainz) Johnson
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:3>

Django

unread,
Aug 12, 2020, 7:20:57 AM8/12/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: assigned
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Adam (Chainz) Johnson):

Using lazy() instead of SimpleLazyObject() fixes this - PR is up.

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:4>

Django

unread,
Aug 12, 2020, 3:32:07 PM8/12/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: assigned
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/13297 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:5>

Django

unread,
Aug 13, 2020, 1:24:39 AM8/13/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: assigned
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:6>

Django

unread,
Aug 13, 2020, 7:13:35 AM8/13/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: closed

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution: fixed

Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"20799cc0a6d98816b9ef0577e24691bd26b80d7d" 20799cc0]:
{{{
#!CommitTicketReference repository=""
revision="20799cc0a6d98816b9ef0577e24691bd26b80d7d"
Fixes #31877 -- Used lazy() for TemplateView kwarg deprecation warning.

SimpleLazyObjects cause a crash when filtering.

Thanks Tim L. White for the report.
Regression in 4ed534758cb6a11df9f49baddecca5a6cdda9311.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:7>

Django

unread,
Aug 13, 2020, 7:14:07 AM8/13/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: closed
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"9ae40d813796b70eb57bb957a19a72213e97179c" 9ae40d81]:
{{{
#!CommitTicketReference repository=""
revision="9ae40d813796b70eb57bb957a19a72213e97179c"
[3.1.x] Fixes #31877 -- Used lazy() for TemplateView kwarg deprecation
warning.

SimpleLazyObjects cause a crash when filtering.

Thanks Tim L. White for the report.
Regression in 4ed534758cb6a11df9f49baddecca5a6cdda9311.

Backport of 20799cc0a6d98816b9ef0577e24691bd26b80d7d from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:8>

Django

unread,
Aug 19, 2020, 2:53:46 AM8/19/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* status: closed => new
* resolution: fixed =>


Comment:

Passing deprecated keyword arguments to a queryset with lookups, e.g.
`Artist.objects.get(name__iexact=artist_name)`, still crashes on
PostgreSQL:
{{{
django.db.utils.ProgrammingError: can't adapt type '__proxy__'
}}}
Thanks Mohit Solanki for the report.

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:9>

Django

unread,
Aug 19, 2020, 6:25:32 PM8/19/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Adam (Chainz) Johnson):

😟 Hmm this is a tough one.

psycopg2 uses `type(obj)` to look for its "adapter" - in its C extension:
https://github.com/psycopg/psycopg2/blob/e14e3385b4809ec4223894f8c7a009b1560eb41d/psycopg/microprotocols.c#L151
. So this "proxy" approach may not be feasible.

I know of a more accurate proxy wrapper that proxies more attributes than
Django's lazy objects - wrapt.ObjectProxy -
https://wrapt.readthedocs.io/en/latest/wrappers.html#object-proxy. But
docs there acknowledge that it can't even make `type()` work, whilst it
makes `isinstance()` work.

Any ideas of alternative approaches?

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:10>

Django

unread,
Aug 21, 2020, 12:12:24 AM8/21/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* has_patch: 1 => 0
* stage: Ready for checkin => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:11>

Django

unread,
Aug 21, 2020, 3:24:35 PM8/21/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tom Forbes):

There isn't really a general purpose way of wrapping primitive/arbitrary
types like this in Python that won't hit some corner cases. You can make
an object appear to be a duck by adapting it's quacking dynamically (i.e
`wrapt.ObjectProxy`), but if someone looks close enough they can always
see that it's actually dog. And on the whole that's a good thing, IMO.

Our use of `kwargs` makes this harder as we lose the ability to construct
a container that can trigger the deprecation warning which would be the
typical easy approach. There is no way to control what lands on the other
side of `get_context_data()` (it's always a plain kwargs dict), and there
is no way to construct a wrapper value that looks _exactly_ like the value
it's wrapping.

That basically leaves only "crazy" approaches, some of which are fun to
consider but none of which are suitable. Here's one that uses `settrace()`
to do what we need:

{{{
import sys

class DeprecatedWrapper(dict):
def __getitem__(self, key):
warnings.warn("stop right there, scoundrel!")
return super().__getitem__(key)

def wrap_kwargs(frame, *args):
frame['kwargs'] = DeprecatedWrapper(frame['kwargs'])
sys.settrace(None)

class TemplateView(...):
def get(...):
...
sys.settrace(wrap_kwargs)
context = self.get_context_data(**context_kwargs)
return self.render_to_response(context)
}}}

Given these issues, I'm not sure if we can go ahead with deprecating this.

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:12>

Django

unread,
Aug 21, 2020, 3:24:42 PM8/21/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tom Forbes):

* cc: Tom Forbes (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:13>

Django

unread,
Aug 24, 2020, 3:19:20 AM8/24/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by felixxm):

* has_patch: 0 => 1


Comment:

Agreed, we should revert it since we don't have a clear deprecation path.

[https://github.com/django/django/pull/13341 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:14>

Django

unread,
Aug 24, 2020, 5:21:03 AM8/24/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: new

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Adam (Chainz) Johnson):

I agree too.

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:15>

Django

unread,
Aug 24, 2020, 5:38:18 AM8/24/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: closed

Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"bb8f66934d93faf80cd1a2dda65aaedce21a6fc5" bb8f6693]:
{{{
#!CommitTicketReference repository=""
revision="bb8f66934d93faf80cd1a2dda65aaedce21a6fc5"
Fixed #31877 -- Reverted "Fixed #19878 -- Deprecated TemplateView passing
URL kwargs into context."

This reverts commit 4ed534758cb6a11df9f49baddecca5a6cdda9311.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:17>

Django

unread,
Aug 24, 2020, 5:38:18 AM8/24/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: closed
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak <felisiak.mariusz@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"04e87e79a0bd2b1b9fdc30f884a637a3268733f0" 04e87e79]:
{{{
#!CommitTicketReference repository=""
revision="04e87e79a0bd2b1b9fdc30f884a637a3268733f0"
Refs #31877 -- Reverted "Fixes #31877 -- Used lazy() for TemplateView
kwarg deprecation warning."

This reverts commit 20799cc0a6d98816b9ef0577e24691bd26b80d7d.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:16>

Django

unread,
Aug 24, 2020, 5:39:46 AM8/24/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: closed
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"f247c66bb5f95541d16143ef37452bb1dfeacc3e" f247c66b]:
{{{
#!CommitTicketReference repository=""
revision="f247c66bb5f95541d16143ef37452bb1dfeacc3e"
[3.1.x] Refs #31877 -- Reverted "Fixes #31877 -- Used lazy() for
TemplateView kwarg deprecation warning."

This reverts commit 20799cc0a6d98816b9ef0577e24691bd26b80d7d.

Backport of 04e87e79a0bd2b1b9fdc30f884a637a3268733f0 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:18>

Django

unread,
Aug 24, 2020, 5:39:46 AM8/24/20
to django-...@googlegroups.com
#31877: TemplateView.get_context_data()'s kwargs returns SimpleLazyObjects that
causes a crash when filtering.
-------------------------------------+-------------------------------------
Reporter: Tim L. White | Owner: Adam
| (Chainz) Johnson
Type: Bug | Status: closed
Component: Generic views | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak <felisiak.mariusz@…>):

In [changeset:"e81aa7a94addf1f5380960fe89a49d104889c96d" e81aa7a]:
{{{
#!CommitTicketReference repository=""
revision="e81aa7a94addf1f5380960fe89a49d104889c96d"
[3.1.x] Fixed #31877 -- Reverted "Fixed #19878 -- Deprecated TemplateView


passing URL kwargs into context."

This reverts commit 4ed534758cb6a11df9f49baddecca5a6cdda9311.

Backport of bb8f66934d93faf80cd1a2dda65aaedce21a6fc5 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/31877#comment:19>

Reply all
Reply to author
Forward
0 new messages