2013-07-07 95 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好了,修正 –

相关问题