Opened 13 years ago

Closed 10 years ago

Last modified 9 years ago

#15040 closed Bug (fixed)

Boolean fields return 0 and 1 when loaded through select_related

Reported by: homm Owned by: nobody
Component: Database layer (models, ORM) Version: 1.4
Severity: Normal Keywords:
Cc: benjaoming@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

This behavior only on mysql. SQLite always return True or False.

Models.py file:

from django.db import models

class BoolModel(models.Model):
    bool = models.BooleanField()

class Parent(models.Model):
    true = models.ForeignKey(BoolModel, related_name='trues')
    false = models.ForeignKey(BoolModel, related_name='falses')

In command line:

./manage.py shell
>>> from ex.models import *
>>> true = BoolModel.objects.create(bool=True)
>>> false = BoolModel.objects.create(bool=False)
>>> parent = Parent.objects.create(true=true, false=false)

>>> parent = Parent.objects.get()
>>> parent.true.bool
True
>>> parent.false.bool
False

>>> parent = Parent.objects.select_related('true', 'false').get()
>>> parent.true.bool
1
>>> parent.false.bool
0

As you can seen, in first case, when parent object loaded without select_related, booleans is booleans.
In second case, when object loaded with select_related, boolens are numbers.

Version 1.2 and 1.3 acts the same.

Attachments (2)

15040.diff (4.1 KB ) - added by Ramiro Morales 12 years ago.
Patch, includes tests
15040-anon-test.diff (1.1 KB ) - added by Tim Graham 10 years ago.

Download all attachments as: .zip

Change History (19)

comment:1 by Russell Keith-Magee, 13 years ago

Triage Stage: UnreviewedAccepted

This is because MySQL has special handling for returning boolean values; in 1.2, we added some callbacks to do the post-processing to ensure values get rectified. However, that rectification is performed with reference to the original model field. When using select_related, the original model obviously isn't being carried along for the ride.

comment:2 by Adam Nelson, 13 years ago

Change at #15169 may be related and address this

comment:3 by anonymous, 13 years ago

milestone: 1.3
Severity: Normal
Type: Bug

comment:4 by Aymeric Augustin, 12 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:5 by Aymeric Augustin, 12 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:6 by Ramiro Morales, 12 years ago

Has patch: set

by Ramiro Morales, 12 years ago

Attachment: 15040.diff added

Patch, includes tests

comment:7 by anonymous, 12 years ago

I just spent a ton of time debugging to figure out what this bug is. It causes ModelForms to have checkboxes that are all checked.

comment:8 by benjaoming, 12 years ago

Cc: benjaoming@… added

*bump* there is a patch for this! It even contains a very neat set of tests. Can it be merged and the bug closed? :)

comment:9 by anonymous, 11 years ago

Version: 1.21.4

In my opinion this is a fairly significant issue. I spent all morning trying to figure out why a ModelForm (which was working perfectly locally on SQLite) had broken checkbox fields when deployed with a mysql backend.

parent = ParentModel.objects.select_related('child').get(pk=id)
# BooleanFields won't work with this form if using MySQL because their values are rendered as ints due to select_related()
child_form = ChildModelForm(instance=parent.child)

If there's no easy fix to this in Django itself I think there should at least be a warning in the documentation letting users know of this issue.

comment:10 by Luke Plant <L.Plant.98@…>, 11 years ago

Resolution: fixed
Status: newclosed

In f3a2bcdee906f7ca1434b6275fdc09b3a454cf46:

Fixed #15040 - Boolean fields return 0 and 1 when loaded through select_related

Thanks to homm for the report and ramiro for the patch.

comment:11 by Luke Plant <L.Plant.98@…>, 11 years ago

In 142f69eb8c79ea5a54799354231b219f7c53b1cc:

[1.5.x] Fixed #15040 - Boolean fields return 0 and 1 when loaded through select_related

Thanks to homm for the report and ramiro for the patch.

Backport of f3a2bcdee906f7ca1434b6275fdc09b3a454cf46 from master

comment:12 by anonymous, 11 years ago

Resolution: fixed
Status: closednew

I am having this problem in 1.5.1 -- 0 when using select related, but False when not. I am using mysql.

comment:13 by anonymous, 11 years ago

The problem only occurs when using .defer()

by Tim Graham, 10 years ago

Attachment: 15040-anon-test.diff added

comment:14 by Tim Graham, 10 years ago

Resolution: fixed
Status: newclosed

@anonymous, please open a new ticket with a test case if you can reproduce the issue on master. I tried the attached test based on your vague description but it passes on master and 1.5.x.

comment:15 by Anssi Kääriäinen, 10 years ago

I am pretty sure this one was fixed in #21203 and #21126, both of which got backpatched to 1.5.

comment:16 by Kyle Gibson, 9 years ago

I apologise if this isn't the proper place for this comment, but what would it take to get this fix backpatched to 1.4?

in reply to:  16 comment:17 by Carl Meyer, 9 years ago

Replying to kylegibson:

I apologise if this isn't the proper place for this comment, but what would it take to get this fix backpatched to 1.4?

I'm afraid it won't be. 1.4 is in security-fix-only mode.

Note: See TracTickets for help on using tickets.
Back to Top