Merge pull request #4201 from normanjaeckel/ManyToManyFix

Fixed autoupdate for m2m relation.
This commit is contained in:
Norman Jäckel 2019-03-06 09:31:18 +01:00 committed by GitHub
commit d9369ab9c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 2 deletions

View File

@ -17,7 +17,7 @@ Core:
- Enabled docs for using OpenSlides with Gunicorn and Uvicorn in big - Enabled docs for using OpenSlides with Gunicorn and Uvicorn in big
mode [#3799, #3817]. mode [#3799, #3817].
- Changed format for elements send via autoupdate [#3926]. - Changed format for elements send via autoupdate [#3926].
- Fixed autoupdate system for related objects [#4140]. - Fixed autoupdate system for related objects [#4140, #4201].
- Add a change-id system to get only new elements [#3938]. - Add a change-id system to get only new elements [#3938].
- Switch from Yarn back to npm [#3964]. - Switch from Yarn back to npm [#3964].
- Added password reset link (password reset via email) [#3914, #4199]. - Added password reset link (password reset via email) [#3914, #4199].

View File

@ -6,7 +6,7 @@ from typing import Any, Dict, List, Set
from django.apps import AppConfig from django.apps import AppConfig
from django.conf import settings from django.conf import settings
from django.db.models.signals import post_migrate from django.db.models.signals import post_migrate, pre_delete
class CoreAppConfig(AppConfig): class CoreAppConfig(AppConfig):
@ -20,6 +20,7 @@ class CoreAppConfig(AppConfig):
from .projector import register_projector_slides from .projector import register_projector_slides
from . import serializers # noqa from . import serializers # noqa
from .signals import ( from .signals import (
autoupdate_for_many_to_many_relations,
delete_django_app_permissions, delete_django_app_permissions,
get_permission_change_data, get_permission_change_data,
permission_change, permission_change,
@ -64,6 +65,10 @@ class CoreAppConfig(AppConfig):
sender=self, sender=self,
dispatch_uid="core_save_config_default_values", dispatch_uid="core_save_config_default_values",
) )
pre_delete.connect(
autoupdate_for_many_to_many_relations,
dispatch_uid="core_autoupdate_for_many_to_many_relations",
)
# Register viewsets. # Register viewsets.
router.register( router.register(

View File

@ -4,6 +4,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import Q from django.db.models import Q
from django.dispatch import Signal from django.dispatch import Signal
from ..utils.autoupdate import Element, inform_changed_elements
# This signal is send when the migrate command is done. That means it is sent # This signal is send when the migrate command is done. That means it is sent
# after post_migrate sending and creating all Permission objects. Don't use it # after post_migrate sending and creating all Permission objects. Don't use it
@ -40,3 +42,32 @@ def get_permission_change_data(sender, permissions, **kwargs):
yield core_app.get_model("Countdown") yield core_app.get_model("Countdown")
elif permission.codename == "can_use_chat": elif permission.codename == "can_use_chat":
yield core_app.get_model("ChatMessage") yield core_app.get_model("ChatMessage")
def autoupdate_for_many_to_many_relations(sender, instance, **kwargs):
"""
Send autoupdate for many-to-many related objects if the other side
is deleted.
"""
m2m_fields = (
field
for field in instance._meta.get_fields(include_hidden=True)
if field.many_to_many and field.auto_created
)
for field in m2m_fields:
queryset = getattr(instance, field.get_accessor_name()).all()
for related_instance in queryset:
if hasattr(related_instance, "get_root_rest_element"):
# The related instance is or has a root rest element.
# So lets send it via autoupdate.
root_rest_element = related_instance.get_root_rest_element()
inform_changed_elements(
[
Element(
collection_string=root_rest_element.get_collection_string(),
id=root_rest_element.pk,
full_data=None,
reload=True,
)
]
)