Deactivate the Child Objects when parent is deactivate.

31 views
Skip to first unread message

pradam programmer

unread,
May 28, 2017, 11:51:58 AM5/28/17
to django...@googlegroups.com
from django.db.models import QuerySet
import attr
from attr.validators import instance_of

@attr.s
class ChildDeactivate(object):
    loca = attr.ib(validator=instance_of(QuerySet))

    def deactivate_child(self,l):
        get_parent = Boundary.objects.filter(parent__id=l.id)
        if get_parent:
            deact_child = map(lambda x: x.switch(),get_parent)
        else:
            l.switch()
        return l.name, l.get_active_display(), l.boundary_level

    def list_all(self):
        for i in self.loca:
            name_bound, status, level = self.deactivate_child(i)
            print '{} is change to {} status of level {}'.format(name_bound, status, level)

l = Boundary.objects.filter(parent__id=2)
s = ChildDeactivate(l)
s.list_all()

In my location models i have 9 levels, i wrote this snippet to deactivate children objects when parent is deactivated, so anything to do to make it more generic all the over models..?

James Schneider

unread,
May 29, 2017, 3:20:12 AM5/29/17
to django...@googlegroups.com
On Sun, May 28, 2017 at 8:50 AM, pradam programmer <pradam.pr...@gmail.com> wrote:
from django.db.models import QuerySet
import attr
from attr.validators import instance_of

@attr.s
class ChildDeactivate(object):
    loca = attr.ib(validator=instance_of(QuerySet))

    def deactivate_child(self,l):
        get_parent = Boundary.objects.filter(parent__id=l.id)
        if get_parent:
            deact_child = map(lambda x: x.switch(),get_parent)
        else:
            l.switch()
        return l.name, l.get_active_display(), l.boundary_level

    def list_all(self):
        for i in self.loca:
            name_bound, status, level = self.deactivate_child(i)
            print '{} is change to {} status of level {}'.format(name_bound, status, level)

l = Boundary.objects.filter(parent__id=2)
s = ChildDeactivate(l)
s.list_all()


This should be generalized as an abstract model (https://docs.djangoproject.com/en/1.11/topics/db/models/#abstract-base-classes) and any models with children should inherit from it. 

# example
class HasChildren(models.Model):

    activated = models.BooleanField(default=False)

    def get_children(self):
        # logic to return a list of children models

    def set_activation_status(self, new_status):
        # logic to deactivate this node
        self.activated = new_status
        self.save()

    def set_children_activation_status(self, new_status):
        # get list from self.get_children()
        # run self.set_activation_status(new_status) on all members in list
        # If every model is same type, may be more efficient to use an update query, something like
        # self.__class__.objects.filter(id=[list of children]).update(activated=new_status)
        
    class Meta:
        abstract = True

 
In my location models i have 9 levels, i wrote this snippet to deactivate children objects when parent is deactivated, so anything to do to make it more generic all the over models..?

Using an abstract model class and only referring to self (rather than a specific class), you can keep your code DRY and generic. 

If all of the parents and children are the same model type, you may be able to take advantage of an MPTT tree (ie http://django-mptt.github.io/django-mptt/), which will allow you to maintain an ordered parent->child relationship (and even siblings if needed), while reducing the number of queries needed to pull/modify all of the parents and children in the hierarchy (in most cases, 1). 

-James
Reply all
Reply to author
Forward
0 new messages