Django

Code

Ticket #7076 (closed: fixed)

Opened 7 months ago

Last modified 5 months ago

qs.exclude(something=123) should not exclude objects with something=None

Reported by: Thomas Steinacher <tom@eggdrop.ch> Assigned to:
Milestone: 1.0 Component: Database layer (models, ORM)
Version: SVN Keywords: qsrf-cleanup
Cc: Triage Stage: Accepted
Has patch: 1 Needs documentation: 1
Needs tests: 1 Patch needs improvement: 1

Description

from django.db import models
class A(models.Model):
    str = models.CharField(null=True, blank=True, max_length=20)
    def __unicode__(self):
        return self.str or 'None'
In [1]: from test import models

In [2]: a = models.A.objects.create(str='a')

In [3]: b = models.A.objects.create(str=None)

In [4]: models.A.objects.exclude(str='a')
Out[4]: []

In [5]: models.A.objects.filter(str__isnull=True).exclude(str='a')
Out[5]: []

In [6]: models.A.objects.all()                                    
Out[6]: [<A: a>, <A: None>]

Expected output:

Out[4]: [<A: None>]  
Out[5]: [<A: None>]  

Tested with trunk & queryset-refactor.

Attachments

7076.1.diff (1.6 kB) - added by emulbreh on 06/12/08 11:39:21.

Change History

06/10/08 11:01:40 changed by gav

  • keywords set to qsrf-cleanup.
  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

06/12/08 11:39:21 changed by emulbreh

  • attachment 7076.1.diff added.

06/12/08 11:40:26 changed by emulbreh

  • status changed from new to assigned.
  • needs_better_patch set to 1.
  • needs_tests set to 1.
  • owner changed from nobody to anonymous.
  • needs_docs set to 1.
  • has_patch set to 1.

I can reproduce this (r7573 + postgres).

It could be solved easyly by making __exact NULL-safe:

But I couldn't find something comparable for sqlite and oracle (except for (a=b OR (a IS NULL AND b IS NULL))) - and I don't know if anything depends on NULL == 1=NULL == NOT (1=NULL) and would break with FALSE == 1<=>NULL != NOT(1<=>NULL) == TRUE.

While trying to come up with a patch I found some dead code that should handle the issue for related tables (see patch, missing [JOIN_TYPE] in if final > 1 ...) and just threw in a similar weakening for the unjoined case.

This will be a backwards incompatible change.

06/12/08 11:42:29 changed by anonymous

  • owner deleted.
  • status changed from assigned to new.
  • stage changed from Unreviewed to Accepted.

06/16/08 12:10:45 changed by jacob

  • milestone set to 1.0.

06/26/08 00:32:20 changed by mtredinnick

Thanks for the patch, but ... one way to tell that a patch isn't quite correct is when the existing test suite doesn't pass when it's applied. :-)

This patch breaks the exclude(field__in=[]) case. I'll fix it before committing and add some tests for the issues in this ticket, but please check the test suite and include tests for any new functionality. It makes things easier.

06/26/08 00:36:53 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

Fixed in [7760].

07/01/08 05:12:50 changed by mtredinnick

(In [7812]) Modified [7760] to not include a "col is not NULL" fragment for non-nullable fields.

This avoids any use of "pk is not NULL" fragment, which behave inconsistently in MySQL. Thanks to Russell Keith-Magee for diagnosing the problem and suggesting the easy fix.

Refs #7076.


Add/Change #7076 (qs.exclude(something=123) should not exclude objects with something=None)




Change Properties
Action