我有一个带有m2m字段持有分支的Business模型。有些企业有分支机构,有些则没有。
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-10A...和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来实现?
发布于 2017-09-29 08:59:29
如果不建议一个库,这并不是一件容易的事情。您正在谈论递归,这在编程中是一项棘手的任务,特别是如果您太深入的话。不过,您可以使用django-mptt在多个层次上做到这一点。文档对此进行了很好的解释,这可以在here找到。不过,它很容易实现。
发布于 2017-09-29 11:29:52
好吧,我认为你应该把表示信息放在你的模型里。
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)) 如果你有很多业务要处理,最后一个循环会慢得可怕。当然,有更聪明的方法可以做到这一点。
https://stackoverflow.com/questions/46479852
复制相似问题