2017-09-28 15 views
1

Business m2mフィールドのブランチが保持されます。一部の企業ではないブランチがあります。m2mフィールドから1つのオブジェクトを持つオブジェクトのリストを取得すると、

class Business(models.Model): 
    order = models.IntegerField() 
    branches = models.ManyToManyField('self') 

そして、私は(ビジネスが支店を持っている場合)チェーンからわずか1(上)支店で注文(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...オブジェクトは、分岐を有していて、BCEDにはありません。

私が取得したいリストは、次のとおりです。私は1つのブランチを除いて、最終的なリストから任意の事業の全ての枝を除外したい言い換えれば

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などとは何か? Orderは整数フィールドであり、この形式をサポートしていません。 – Tico

+0

実ビジネスオブジェクトの単純な表現。最初の文字はチェーンに属することを意味し、数字はソート順を意味します。それは私が何を意味するかを示す単なるモデルです。 – Ilya

+0

したがって、1つのビジネスオブジェクトを指定すると、それを照会する必要があり、それらの要件を満たすブランチが返されます。これは正しいです? – Tico

答えて

0

これは、ライブラリを提案するだけでは簡単には答えられません。あなたは再帰について話していますが、これはプログラミングの面倒な作業です。あなたはdjango-mpttでこれを多くのレベル深くすることができます。ドキュメントはかなり良い説明し、それはhereが見つかりました。しかし、実装するのはかなり簡単です。

+0

MPTTには親オブジェクトと子オブジェクトがありますが、私の場合は階層構造ではありません。すべての枝が等しい。企業には本社(親会社)と支店(子会社)はありません。 – Ilya

+0

私はあなたがあなたがしていないことを望んでいたと思っています。対称性を偽に設定することは、あなたが必要とするものでしょうか?私はこれらの関係をどのように整理する必要があるかについては不明です。 –

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

は、あなたがその必要出力ファイルルックス

あなたは多くのビジネスを通過する場合、この最後のループはひどく遅いです。確かにこれを行うよりスマートな方法があります。

関連する問題