2017-09-28 4 views
1

Business m2m 필드에 분기가있는 모델이 있습니다. 일부 기업은 가지가없는 지점이 있습니다.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, ED하지 않습니다.

내가 얻고 싶은 목록입니다 : 내가 한 가지를 제외하고 최종 목록에서 모든 비즈니스의 모든 지점을 제외 할 즉

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

AA-0, AB-1 등이란 무엇입니까? 주문은 정수 필드이며이 형식을 지원하지 않습니다. – Tico

+0

실제 비즈니스 오브젝트의 간단한 표현. 첫 번째 문자는 체인에 속하는 것을 의미하며 숫자는 정렬 순서를 의미합니다. 제가 의미하는 바를 보여주는 모델 일뿐입니다. – Ilya

+0

그래서 하나의 비즈니스 객체가 주어진다면, 당신은 그것을 쿼리하기를 원한다. 이 올바른지? – Tico

답변

0

이것은 라이브러리를 제안하지 않고도 쉽게 대답 할 수 없습니다. 당신은 재귀에 대해 이야기하고 있으며, 특히 프로그래밍이 너무 깊어지면 프로그래밍에있어 까다로운 작업입니다. 당신은 django-mptt로 많은 수준을 깊게 할 수 있습니다. 설명서에 잘 설명되어 있으며 here입니다. 꽤 구현하기 쉽습니다.

+0

MPTT에는 부모 개체와 자식 개체가 있지만 내 경우에는 계층 구조가 아닙니다. 모든 가지가 동일합니다. 기업에는 본사 (학부모)와 지부 (자녀)가 없습니다. – Ilya

+0

나는 네가 원하지 않는 것을 원한다고 생각했다. 대칭을 false로 설정하는 것이 필요한 것입니까?이 관계를 주문하는 방법에 대해 분명하지 않습니다. –

+0

여기에 사용 된 것과 같은 의미입니다. https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.ManyToManyField.symmetrical –

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) 

, 비즈니스 오브젝트를 지정해, 각 첫 글자의 최소에 대한 정보를 얻기 위해 다음과 같이 수행 할 수 있습니다

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)) 
:

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...] 

당신이 원하는 출력 파일 같은데

많은 사업을해야하는 경우이 마지막 루프는 매우 느립니다. Ceirtainlly 이것을하는 더 똑똑한 방법이 있습니다.