* cc: kmike84@… (added)
* ui_ux: => 0
* easy: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:9>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: sfllaw@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:10>
Comment (by sfllaw):
Because {{{__set__()}}} clears and adds, it does a lot of extra work when
assignment happens, since each object in the new set has to be INSERTed in
the database, even if it's just to add an extra item.
The extra query can be eliminated in {{{_add_items()}}}, which can be told
that its list of {{{*objs}}} do not already exist so it doesn't have to
check for them.
We've hit this problem with m2m_changed on any {{{ModelForm}}}, so it's
not just limited to the admin site.
If there's interest, I can write up a patch that implements this.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:11>
* cc: jblaine@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:12>
Comment (by jblaine):
I'm interested in ''any'' patch that will give me access to the new data
and operations performed when a model's m2m field is altered. Right now,
m2m_changed is totally useless to me, and is actually '''dangerous''' as
others have pointed out in other bugs related to this one.
Me: ''Remove 2 relationships from these 200 that are set.''
Admin: ''Okay! I removed 200 things and added all 198 items back that did
not match your 2! And I sent not one single pre_remove or post_remove
signal!''
Me: ''That's not at all what I said, and it totally matters how you go
about it and that your signals+actions properly reflect what is being
asked and not reflecting how you went about doing it.''
I suspect it's no surprise that I consider this a bug, not a
"cleanup/optimization" as it's now categorized :(
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:13>
* type: Cleanup/optimization => Bug
Comment:
Closed #16073 (which was specifically about incorrect m2m signals in the
admin, as a result of this) as duplicate. Marking this a bug rather than a
cleanup/optimization; previous to the existence of m2m signals it may have
been the latter, but at this point the signaling problem makes it a bug.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:14>
* owner: nobody => sfllaw
* needs_better_patch: 1 => 0
* status: new => assigned
Comment:
6707_m2m_set.diff includes a patch that performs the minimum amount of
DELETE and INSERT statements for the {{{__set__}}} method. In addition, I
have changed {{{_add_items()}}} so it does not do an extra SELECT if
{{{__set__}}} has already removed duplicates, so we do not perform an
extra query.
This patch applies to SVN trunk.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:15>
Comment (by sfllaw):
It occurred to me, while writing this patch, that the {{{__set__}}}
methods for ManyRelatedObjectsDescriptor and
ReverseManyRelatedObjectsDescriptor are basically the same. Should those
two Descriptors be unified into a base descriptor?
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:16>
* cc: bradley.ayers@… (added)
Comment:
This is fantastic, I just wanted to say thank-you very much for writing
this latest patch!
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:17>
Comment (by akaariai):
I haven't tested this ticket, just skimmed the latest patch. To me it
seems this is worth getting into Django, the savings can be pretty large
if one regularly does small changes to m2m fields using list assignment.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:18>
Comment (by sfllaw):
akaariai: Are there any improvements to this patch that you can suggest?
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:19>
Comment (by akaariai):
Not anything I spotted immediately. As said, I haven't gone through this
in full detail. If you can get somebody to review the patch it would of
course be a plus.
I will try to get time to work on this. I can't promise anything, though.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:20>
Comment (by sfllaw):
It'd be great to get a core developer to look at whether the suggested
refactoring above would be sensible.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:21>
* cc: flavio.curella@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:22>
* cc: botondus@… (added)
Comment:
Ran into this as well on multiple occasions.
This basically makes the m2m_changed signal almost useless :(
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:23>
Comment (by ivan_virabyan):
As I understand there is currently no way to determine which values were
added to many2many field in the admin?
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:24>
* cc: info@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:25>
Comment (by a.krille@…):
Any news on this?
We too are bidden by this bug (and it is a bug when a signal is documented
but never actually emitted) and would love to see a proper fix.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:26>
* cc: info@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:27>
Comment (by anonymous):
This bug was opened "6 years ago" and we are still around the "patch".
What would it take to get this fixed?
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:28>
Comment (by anonymous):
Shouldn't at least the documentation for previous versions including
version 1.6 be updated to not include the pre_remove and post_remove
actions in the m2m-changed signal?
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:29>
* owner: sfllaw => loic84
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:30>
Comment (by anonymous):
Bitten too.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:31>
* needs_better_patch: 0 => 1
* needs_tests: 0 => 1
* needs_docs: 0 => 1
Comment:
There's no documentation yet and I still want to add more tests, but the
latest effort for this issue is at
https://github.com/django/django/pull/2500.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:32>
* owner: loic84 => loic
* needs_docs: 1 => 0
* needs_tests: 1 => 0
Comment:
Resuming work on this issue, I brought the branch up-to-date and drafted
some documentation. It'd be very helpful if some of those affected by this
issue could give it a try.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:33>
Comment (by nlundquist):
I've tested the branch Loic has worked on and my primary issue still
remains. m2m_changed is not triggered when the relationship is altered via
a StackInline admin form.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:34>
* cc: cmawebsite@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:35>
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:36>
Comment (by loic):
I've rebased the PR and I'm quite happy with the result.
I checked regarding comment:34 and indeed when M2M are displayed as admin
inlines `m2m_changed` isn't triggered. It's because the M2M field is
bypassed and the `through` table is seen by the admin as a normal model
with 2 FKs. That's an orthogonal problem but I added docs about it in the
PR.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:37>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:38>
Comment (by Loic Bistuer <loic.bistuer@…>):
In [changeset:"9d104a21e20f9c5ec41d19fd919d0e808aa13dba"]:
{{{
#!CommitTicketReference repository=""
revision="9d104a21e20f9c5ec41d19fd919d0e808aa13dba"
Documented that m2m_changed isn't triggered when M2M is displayed as admin
inline.
Refs #6707.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:40>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"71ada3a8e689a883b5ffdeb1744ea16f176ab730"]:
{{{
#!CommitTicketReference repository=""
revision="71ada3a8e689a883b5ffdeb1744ea16f176ab730"
Fixed #6707 -- Added RelatedManager.set() and made descriptors' __set__
use it.
Thanks Anssi Kääriäinen, Carl Meyer, Collin Anderson, and Tim Graham for
the reviews.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:39>
Comment (by Loic Bistuer <loic.bistuer@…>):
In [changeset:"20eb51ce0ddcb8d5fdc772fc2839fefef5b28c2a"]:
{{{
#!CommitTicketReference repository=""
revision="20eb51ce0ddcb8d5fdc772fc2839fefef5b28c2a"
Fix small regression caused by 71ada3a8e689a883b5ffdeb1744ea16f176ab730.
During direct assignment, evaluating the iterable before the transaction
is started avoids leaving the transaction dirty if an exception is raised.
This is slightly more wasteful but probably not enough to warrant a change
of behavior.
Thanks Anssi for the feedback. Refs #6707.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:41>
Comment (by psychok7):
@Loic is this commit going to be released for Django 1.7 still ??? I am
using Django 1.7.8 and i noticed that its not there yet
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:42>
Comment (by collinanderson):
@psychok7 this is actually considered more of a new feature /
optimization, so it's not backported to 1.7. It actually missed the
deadline for getting into 1.8 by a few weeks, but it will be in 1.9 which
comes out towards the end of the year.
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:43>
* cc: toracle@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/6707#comment:44>