我有Business
模型,m2m字段保存分支。有些企业有分支,有些企业没有。
class Business(models.Model):
order = models.IntegerField()
branches = models.ManyToManyField('self')
我想获得有序(由order
字段)业务的列表,其中只有一个(顶级)分支来自链(如果业务有分支)。
例如,让第一个字母表示属于链,而数字表示排序顺序:
AA-0
AB-1
AC-2
AD-3
B-4
C-5
D-6
E-7
FA-8
FB-9
FC-10
A...
和F...
个对象有分支,B
,C
,E
和D
没有分支。
我想要的清单是:
AA, B, C, D, E, FA
换句话说,除了一个分支外,我想从最终列表中排除任何业务的所有分支。我需要在列表中存在业务,但没有分支。
我是如何用双循环完成的:
object_list = Business.objects.all().order_by('order')
object_list_no_branches = []
for obj in object_list:
found = False
for obj_inner in object_list_no_branches:
found = obj_inner.branches.filter(pk=obj.pk).exists()
if found:
break
if not found:
object_list_no_branches.append(obj)
但显然循环不是我需要的技术。
是否可以使用Django ORM或PostgreSQL?
答案 0 :(得分:0)
如果不建议使用图书馆,这不是一件容易的事。你在谈论递归,这在编程中是一个棘手的任务,特别是如果你太深了。尽管如此,您可以使用django-mptt深入了解这个级别。文档解释得非常好,找到了here。这很容易实现。
答案 1 :(得分:0)
好吧,我认为你应该把这种表示信息放在你的模型中。
class Business(models.Model):
order = models.IntegerField()
chain_id = models.CharFieldField(max_length = '1')
chain_second_letter = models.CharFieldField(max_length = '1')
branches = models.ManyToManyField('self')
def representation:
return '%s%s-%s' % (chain_id,chain_second_letter,order)
然后,给定一个业务对象,您可以这样做以获取有关每个首字母的最小值的信息:
from django.db.models import Min
l = Business.branches.all().values('chain_id').annotate(Min('order')):
## this returns something like
##[{'chain_id':'A',order__min:'1'},
##{'chain_id':'B',order__min:'0'},etc...]
查找文件所需的输出:
final = []
for obj in l:
business = Business.objects.get(chain_id = obj['chain_id'],order = obj['order_min'])
final.append('%s%s' % (business.chain_id,business.chain_second_letter))
如果您有很多业务需要通过,那么最后一个循环非常缓慢。 Ceirtainlly有更聪明的方法来做到这一点。