I’ve been reading up on SQL’s tri-valued logic (TRUE / FALSE / UNKNOWN), which explains why SQL needs IS NULL and IS NOT NULL for comparisons involving NULL. I knew that when writing queries involving blank values one is supposed to use IS NULL, now I understand why. Neat.
As of ticket #31667, filter(fieldin=[None]) now silently ignores None, which means some of the earlier concerns about fixing this no longer apply.
I believe this can be resolved cleanly by checking if None is present in the rhs, and if so, splitting the clause into an IN condition and an IS NULL condition joined by OR. That should align exclude(fieldin=[None, X]) with user expectations and prevent SQL NULL logic from leaking into the ORM unnecessarily.
Assigning to myself and will begin a patch.