Recursion 如何在django rest API中将一个简单func转换为递归func
我有一个对象,它可以有自己的孩子,这个孩子也有自己的孩子,等等。所有这些通道都有字段total_amount_active_Channel,默认为0。当我在任何对象(也在父对象和子对象中)中更改此字段时,更改将影响所有以前的父对象。 例如: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 (
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
你能添加型号吗?我已经添加了