class Topping(models.Model):
meat = models.BooleanField()
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
}}}
{{{
>>> pizza = Pizza.objects.create()
>>> cheese = Topping.objects.create(meat=False)
>>> bacon = Topping.objects.create(meat=True)
>>> pizza.toppings = [cheese, bacon]
>>> pizza.toppings.count()
2
>>> vegs = pizza.toppings.filter(meat=False)
>>> vegs.count()
1
>>> pizza.toppings = vegs
>>> pizza.toppings.count()
0
>>> vegs.count()
0
}}}
Would expect vegs to be unchanged, and pizza.toppings to be [cheese]
The problem is the same if the vegs QS is generated with
Topping.objects.filter(pizza=pizza). If it comes from somewhere not
involving the relation then everything works as expected.
--
Ticket URL: <https://code.djangoproject.com/ticket/19816>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted
Comment:
Yes, because the queryset isn't evaluated until after the existing m2m
values are cleared, meaning it evaluates to an empty queryset. Definitely
a bug. Thanks for the report!
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:1>
* owner: nobody => ethlinn
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:2>
* has_patch: 0 => 1
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:3>
* keywords: => sprint2013
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:4>
Comment (by Honza Král <Honza.Kral@…>):
In [changeset:"6cb6e1128f090d5edde9918ba2ae79c1e38b65ad"]:
{{{
#!CommitTicketReference repository=""
revision="6cb6e1128f090d5edde9918ba2ae79c1e38b65ad"
Merge pull request #769 from oinopion/ticket19816
Fixed #19816 -- pre-evaluate queryset on m2m set
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:6>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"3dddbc0f2380d2654e66c8df4bb40d5e1d42af98"]:
{{{
#!CommitTicketReference repository=""
revision="3dddbc0f2380d2654e66c8df4bb40d5e1d42af98"
Fixed #19816: pre-evaluate queryset on m2m set
In ReverseManyRelatedObjectsDescriptor.__set__, evaluate possible
queryset to avoid problems when clear() would touch data this queryset
returns.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:5>
Comment (by loic84):
This PR fixes the issue for the other types of descriptors:
https://github.com/django/django/pull/2487.
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:7>
Comment (by Loic Bistuer <loic.bistuer@…>):
In [changeset:"20399083f49faceef1e48530822137257bca9d6a"]:
{{{
#!CommitTicketReference repository=""
revision="20399083f49faceef1e48530822137257bca9d6a"
Fixed #19816 -- Pre-evaluate querysets used in direct relation
assignments.
Since assignments on M2M or reverse FK descriptors is composed of a
`clear()`,
followed by an `add()`, `clear()` could potentially affect the value of
the
assigned queryset before the `add()` step; pre-evaluating it solves the
problem.
This patch fixes the issue for ForeignRelatedObjectsDescriptor,
ManyRelatedObjectsDescriptor, and ReverseGenericRelatedObjectsDescriptor.
It completes 6cb6e1 which addressed ReverseManyRelatedObjectsDescriptor.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:8>
Comment (by Aymeric Augustin <aymeric.augustin@…>):
In [changeset:"a2407c9577c400bf9931ff1db1d7757afa378162"]:
{{{
#!CommitTicketReference repository=""
revision="a2407c9577c400bf9931ff1db1d7757afa378162"
Merge pull request #2487 from loic/ticket19816
Fixed #19816 -- Pre-evaluate querysets used in direct relation
assignments.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:9>
Comment (by Aymeric Augustin <aymeric.augustin@…>):
In [changeset:"9723e999a0b4acb212210241851dbe75dfbc1a55"]:
{{{
#!CommitTicketReference repository=""
revision="9723e999a0b4acb212210241851dbe75dfbc1a55"
Merge pull request #2495 from loic/ticket19816
Fixed mistake in tests from commit 2039908. Refs #19816.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:11>
Comment (by Loic Bistuer <loic.bistuer@…>):
In [changeset:"da7ab8728c795e1853cea4215469ae3649664c6d"]:
{{{
#!CommitTicketReference repository=""
revision="da7ab8728c795e1853cea4215469ae3649664c6d"
Fixed mistake in tests from commit 2039908. Refs #19816.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19816#comment:10>