[英]Iterating through all foreign key related children of an abstract django model
我試圖迭代給定django模型的所有外鍵相關模型。 可能有13種不同的模型可能具有外鍵關系,但它們都繼承了相同的抽象基類。 我想在一個循環中遍歷所有這些,以修改屬於父類的字段。 我的代碼看起來像。
class ClusteringRecord(models.Model):
"""
An abstract class to hold data that is repeated from model to model
"""
wip = models.ForeignKey(
ClusteringWIP, null=True, on_delete = models.SET_NULL)
cluster_comment = models.CharField(max_length=1000, null=True, blank=True)
class Meta:
abstract = True
class ClusteringNPIRecord(ClusteringRecord):
"""Django Model object representing an NPI record that was not able to be
clustered by automatic clustering logic in the database.
"""
npi_id = models.CharField(max_length=1000, null=True)
npi_number = models.CharField(max_length=1000, null=True)
class ClusteringDEARecord(ClusteringRecord):
"""Django Model object representing a DEA record that was not able to be
clustered by automatic clustering logic in the database.
"""
dea_id = models.CharField(max_length=1000, null=True)
dea_number = models.CharField(max_length=1000, null=True)
我想要使用的代碼如下所示:
def cancel_and_return(request, list_type, wip_id):
"""
destroys lock object and returns user to most recent version of worklist
:param request:
:param wip_id: pk of current ClusteringWIP
:return: HTTP redirect to worklist home
"""
wip = ClusteringWIP.objects.select_related().get(pk=wip_id)
for record in wip.clusteringrecord_set.all():
record.cluster_comment = None
record.save()
wip.delete()
但它告訴我clusteringrecord_set無效。 有沒有辦法迭代這個與提供者相關的類的所有子節點? 否則我使用13個不同的for循環來實現這一點並公然違反DRY方法。
實際上,這個基類適用於可能使用ClusteringWIP作為外鍵的所有13個模型,因此簡單地遍歷所有相關(無論類)將完成相同的事情,所以如果這恰好是最好的方法這樣做,請務必告訴我。 但我仍然很想知道上述問題的答案,無論將來的用法如何。
此外,在我尋找這個答案的旅行中,我偶然發現了一個django pre_delete信號, 這個信號似乎更符合我在這里嘗試做的事情(即刪除了ClusteringWIP時,任何相關模型的'cluster_comment'字段無效如果有人能告訴我一個如何用它來完成我的任務的例子,我將非常感激。
謝謝。
您可以使用ClusteringRecord的subclass ()方法。 例如:
@classmethod
def related_set(cls, wip):
classes = cls.__subclasses__()
return sum([c.objects.filter(wip=wip).all() for c in classes], [])
並使用它來迭代你的對象。
對於pre_delete信號,您需要在應用程序中有一個signals.py文件,它看起來像這樣:
from django.db.models.signals import pre_delete, post_delete
from django.dispatch import receiver
from myapp.models import ClusteringWIP
@receiver(pre_delete, sender=ClusteringWIP)
def on_instance_delete(sender, instance, **kwargs):
instance.on_pre_delete()
使用ClusteringWIP :: on_pre_delete方法如下:
def on_pre_delete(self):
for record in ClusteringRecord.related_set(self):
record.cluster_comment = None
record.save()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.