2013-07-07 96 views
2

Player實例(一隊),例如列表team = [player1, player2, player3]如何通過ManyToMany關係獲得django模型?

我如何「get_or_create」包含這些,只有這三名球員有一個查詢Team

這些都是我的Django模型:

class Player(models.Model): 
    name = models.CharField(max_length=100) 

class Team(models.Model): 
    players = models.ManyToManyField(Player) 
+1

這個答案應該讓你回到正軌 http://stackoverflow.com/questions/5301996/django-many-to-many-query –

+0

我正在回答的權利,但它可能需要一段時間才能真正發佈。 –

+0

你知道,即使你只需要調用'get_or_create'這將是2個查詢? –

回答

1

文檔中說,get_or_create是一條捷徑:

try: 
    obj = Person.objects.get(first_name='John', last_name='Lennon') 
except Person.DoesNotExist: 
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)) 
    obj.save() 

因此,我將它如下適應你的使用情況:

from django.db.models import Q, Count 
import operator 

players = [player1, player2, player3] 

team = Team.objects 
    .filter(reduce(
     operator.and_, 
     [Q(players=player) for player in players] 
    )) 
    .annotate(count=Count('players')) 
    .filter(count=len(players)) 

# Note that this^returns a QuerySet. With your posted model there 
# might exist several teams with exactly the same players. 

if not team.exists(): 
    team = Team.objects.create() 
    team.players.add(*players) 

略微複雜但工作流程相同:

  • 查詢是否存在。
  • 如果不存在,創建。
+0

我接受了你的答案,但是我注意到了一個小錯誤。 'team.players.add()'不接受可迭代的,但多個參數,所以它應該是'team.players.add(* players)'使用python的[解包特性](http://docs.python。組織/ 2 /教程/ controlflow.html#拆包參數的-列表)。看看它[在Django文檔](https://docs.djangoproject.com/en/dev/ref/models/relations/#django.db.models.fields.related.RelatedManager.add)。 – kissgyorgy

+0

@Walkman好了,修正 –

相關問題