Recursion 如何在django rest API中将一个简单func转换为递归func

Recursion 如何在django rest API中将一个简单func转换为递归func,recursion,while-loop,django-rest-framework,Recursion,While Loop,Django Rest Framework,我有一个对象,它可以有自己的孩子,这个孩子也有自己的孩子,等等。所有这些通道都有字段total_amount_active_Channel,默认为0。当我在任何对象(也在父对象和子对象中)中更改此字段时,更改将影响所有以前的父对象。 例如: A (parent): if changes = 0, total_amount_active_channels =2 B (child of A): if changes = 0, total_amount_active_channels =2 C (

我有一个对象,它可以有自己的孩子,这个孩子也有自己的孩子,等等。所有这些通道都有字段total_amount_active_Channel,默认为0。当我在任何对象(也在父对象和子对象中)中更改此字段时,更改将影响所有以前的父对象。 例如:

A (parent): if changes = 0,  total_amount_active_channels =2
B (child of A): if changes = 0,  total_amount_active_channels =2
C (child of B): if changes = 1,  total_amount_active_channels =2
D ( child of C): if changes = 1,  total_amount_active_channels = 1
但任何时候当我打开任何对象时,它都应该加上它自己的总\u amount\u active\u channels+它的子对象的总\u amount\u active\u channels。 现在它可以与这段代码一起工作,但我想通过递归重新生成它。我不擅长递归

我的看法是:

class CircuitEditView(generics.RetrieveUpdateAPIView):
    lookup_field = 'pk'
    queryset = Circuit.objects.all()
    serializer_class = CircuitEdit
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated, IsOpuOnly,)

    def perform_update(self, serializer):
        a = bool(self.get_object().first)
        instance = serializer.save(created_by=self.request.user.profile)
        if a != instance.first:
            get_total_amount_active_channels(obj=instance.id_object, instance=instance)
my service.py:

def get_total_amount_active_channels(obj, instance):
    cir = instance.id_object
    while True:
        if cir.id_parent is None:
            if instance.first ==True:
                cir.total_amount_active_channels = int(cir.total_amount_active_channels)+1
                cir.save()
            else:
                cir.total_amount_active_channels = int(cir.total_amount_active_channels) - 1
                cir.save()

            break

        if instance.first == True:
            cir.total_amount_active_channels = int(cir.total_amount_active_channels) + 1
            cir.save()
            cir = cir.id_parent
        else:

            cir.total_amount_active_channels = int(cir.total_amount_active_channels) - 1
            cir.save()
            cir = cir.id_parent
电路型号:

class Circuit(models.Model):
    id_parent = models.ForeignKey('Circuit', on_delete=models.CASCADE, blank=True, null=True)
    num_circuit = models.CharField('Номер канала', max_length=100, blank=True, null=True)   
    name = models.CharField(unique=True, max_length=100, blank=True, null=True)
    first = models.BooleanField('Используется/Не используется', default = False)
    customer = models.ForeignKey(Customer, related_name='circ_cust', on_delete=models.SET_NULL, blank=True, null=True)
    id_object = models.ForeignKey(Object, related_name='circ_obj', on_delete=models.CASCADE, blank=True, null=True)
    
对象的模型:

    
    id_parent = models.ForeignKey('Object', on_delete=models.CASCADE,related_name='parents', blank=True, null=True)
    name = models.CharField('Название', max_length=100)
    
    num = models.CharField('Количество задейственных каналов', max_length=100, blank=True, null=True)
    
    amount_channels = models.CharField('Количество каналов', max_length=100, blank=True, null=True) 
    total_amount_channels = models.CharField(max_length=25, blank=True, null=True)
    total_amount_active_channels = models.CharField(max_length=25, blank=True, null=True)

我会这样做我的递归方法:

def get_total_amount_active_channels(obj, instance):
    cir = instance.id_object

    # update this node
    if instance.first:
        cir.total_amount_active_channels = int(cir.total_amount_active_channels) + 1
    else:
        cir.total_amount_active_channels = int(cir.total_amount_active_channels) - 1

    cir.save()

    if cir.id_parent != None:
        # check for recursion
        get_total_amount_active_channels(obj, cir.id_parent)
def get_total_amount_active_channels(obj, instance):
    cir = instance.id_object
    while True:
        # update this node
        if instance.first:
            cir.total_amount_active_channels = int(cir.total_amount_active_channels) + 1
        else:
            cir.total_amount_active_channels = int(cir.total_amount_active_channels) - 1

        cir.save()

        if cir.id_parent is None:
            break
        else:
            cir = cir.id_parent
无论如何,如果您正在导航的树足够大并且往往比迭代方法慢,那么递归可能会导致内存问题。我将改进迭代方法,而不是实现递归方法

如果您在迭代方法中删除冗余代码,这可能会很好。我会这样做:

def get_total_amount_active_channels(obj, instance):
    cir = instance.id_object

    # update this node
    if instance.first:
        cir.total_amount_active_channels = int(cir.total_amount_active_channels) + 1
    else:
        cir.total_amount_active_channels = int(cir.total_amount_active_channels) - 1

    cir.save()

    if cir.id_parent != None:
        # check for recursion
        get_total_amount_active_channels(obj, cir.id_parent)
def get_total_amount_active_channels(obj, instance):
    cir = instance.id_object
    while True:
        # update this node
        if instance.first:
            cir.total_amount_active_channels = int(cir.total_amount_active_channels) + 1
        else:
            cir.total_amount_active_channels = int(cir.total_amount_active_channels) - 1

        cir.save()

        if cir.id_parent is None:
            break
        else:
            cir = cir.id_parent

你能添加型号吗?我已经添加了