我有一个递归模型。
class Organization(models.Model):
business_name = models.CharField(max_length=100, unique=True)
# recursive relationship
organization = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='organizations')
我有另一个模型是该递归模型的子代,它可以在树中的任何点都是子代。
class Store(models.Model):
registration_no = models.CharField(max_length=8, default=increment_registration_no, unique=True)
organization = models.OneToOneField(Organization, on_delete=models.PROTECT, related_name='store', null=True)
在此应用程序的UI中,商店的列表在具有上面的组织头的递归表中列出。我们有一个专门为此列表设计的序列化器。当用户查看此列表时,他们可以按Organization
和Store
属性进行过滤。
class StoreSerializer(serializers.ModelSerializer):
registration_no = serializers.CharField(read_only=True)
class Meta:
model = Store
fields = ('id', 'registration_no')
class StoreFilterSerializer(serializers.ModelSerializer):
registration_no = serializers.CharField(read_only=True)
def to_representation(self, value):
# Turn single object into a query so that we can use django filters
queryset = Store.objects.filter(pk=value.id)
registration_no = self.context['request'].query_params.get('registration_no', None)
if registration_no is not None:
queryset = queryset.filter(registration_no__icontains=registration_no)
if queryset:
# Represent object with serializer defined above
return StoreSerializer(queryset[0]).data
else:
return {}
class Meta:
model = Store
class OrganizationsSerializer(serializers.ModelSerializer):
store = StoreFilterSerializer(read_only=True)
organizations = RecursiveField(many=True)
class Meta:
model = Organization
fields = ('id', 'business_name', 'organization', 'organizations', 'store')
正如您在上面看到的,如果我们传入registration_no
,则可以将商店过滤掉。但是,假设用户输入的字符串与单个商店不匹配。这样一来,商店将不会退货,但是会退还许多机构。在UI中,由于没有商店行,导致表为空,但由于未过滤组织,因此分页菜单具有每个页面。
所以问题是,在应用商店过滤器(registration_no)之后,如何过滤组织是否在递归树下的某个地方有商店?
答案 0 :(得分:0)
我最终使用的解决方案是过滤所需的商店并获取组织,而不是根据商店属性过滤组织。
过滤商店
各种方法
获取所有商店的父母
all_orgs = []
for store in store_queryset:
all_orgs.push(store.get_all_parents())
获取所有组织 queryset = Organizations.objects.filter(organization__in = all_orgs) 然后返回组织