如何在Django模型中存储ForeignKey列表?

时间:2013-04-16 16:58:08

标签: django django-models

我正在构建一个用户可以购买玩家的平台(比如幻想联盟)。所以我有4个模型:

POSITION_CHOICES = ((1,'1'),
                    (2,'2'),
                    (3,'3'),
                    (4,'4'),
                    (5,'5'),
)

class Team(models.Model):
    ...

class Player(models.Model):
    team = models.ForeignKey(Team, blank=True, null=True, ...)
    position = MultiSelectField(
    user = models.ForeignKey(User, unique=True)
    player1 = models.ForeignKey(Player, related_name='+', blank=True,null=True,
                                limit_choices_to={'position__icontains':1},...)
    player2 = ...
    player3 = ...
    player4 = ...
    player5 = ...
    ...

class FantasyTeams(models.Model):
    user = models.ForeignKey(User, unique=True)
    team1 = models.ForeignKey(Team, verbose_name='Team', blank=True, null=True,
                              on_delete=models.SET_NULL)
    ...

基本上Team包含0个或更多PlayersFantasyPlayersFantasyTeams都是用户购买的玩家和团队(他可以购买0到5个玩家和0到1个团队,但这些数字可能会被更改)。 LUTION 我现在这样做的方式非常难看,即使它有效。我现在正在寻找更整洁的东西(因为我发现它根本不是通用的),比如将player#字段替换为包含players列表的ForeignKey字段。我也愿意将两个模型FantasyPlayersFantasyTeams合并为一个包含一个玩家列表(最多5个),一个团队列表(最多1个)和{{ 1}}给它的用户。

在看到类似的问题时,我看到一对多字段被多次提及,但它所做的只是让我更加困惑ForeignKey和{{ 1}}。

您是否可以指示我在Django模型中存储OneToOneField列表?


解决方案

以下内容正在替换之前的ManyToManyFieldForeignKey

FantasyPlayers

现在我是如何创建和保存模型的(通过FantasyTeams):

class FantasyTeam(models.Model):
    user = models.ForeignKey(User, unique=True)
    players = models.ManyToManyField(Player, blank=True, null=True)
    teams = models.ManyToManyField(Team, blank=True, null=True)
    ...

基本上ModelForm包含0个或更多def fantasy_create(request): # Handling form datas if request.method == "POST": form = EditFantasyTeamForm(request.POST) if form.is_valid(): fantasy = FantasyTeam.objects.create(user=request.user) for player in form.cleaned_data['players']: fantasy.players.add(player) for team in form.cleaned_data['teams']: fantasy.teams.add(team) return redirect(...) # Form is not submitted yet else: form = EditFantasyTeamForm() return render_to_response(...) def fantasy_edit(request): # Fetching the FantasyTeam object fantasy = ... # Handling form datas if request.method == "POST": form = EditFantasyTeamForm(request.POST, instance=fantasy) if form.isLUTION_valid(): form.save() return redirect(...) # Form not submitted yet else: form = EditFantasyTeamForm(instance=fantasy) return render_to_response(...)choices=POSITION_CHOICES, max_length=10) ... class FantasyPlayers(models.Model): user = models.ForeignKey(User, unique=True) player1 = models.ForeignKey(Player, related_name='+', blank=True,null=True, limit_choices_to={'position__icontains':1},...) player2 = ... player3 = ... player4 = ... player5 = ... ... class FantasyTeams(models.Model): user = models.ForeignKey(User, unique=True) team1 = models.ForeignKey(Team, verbose_name='Team', blank=True, null=True, on_delete=models.SET_NULL) ... TeamPlayers都是用户购买的玩家和团队(他可以购买0到5个玩家和0到1个团队,但这些数字可能会被更改)。 LUTION 我现在这样做的方式非常难看,即使它有效。我现在正在寻找更整洁的东西(因为我发现它根本不是通用的),比如将FantasyPlayers字段替换为包含FantasyTeams列表的player#字段。我也愿意将两个模型playersForeignKey合并为一个包含一个玩家列表(最多5个),一个团队列表(最多1个)和{{ 1}}给它的用户。

在看到类似的问题时,我看到一对多字段被多次提及,但它所做的只是让我更加困惑FantasyPlayers和{{ 1}}。

您是否可以指示我在Django模型中存储FantasyTeams列表?


解决方案

以下内容正在替换之前的ForeignKeyOneToOneField

ManyToManyField

现在我是如何创建和保存模型的(通过ForeignKey):

FantasyPlayers

2 个答案:

答案 0 :(得分:2)

您应该使用ManyToManyField

players = models.ManyToManyField(Player, ...)

但是,只有Player实例可以属于多个FantasyPlayers实例(Team同样的事情),如果Player实例只能属于一个FantasyPlayers实例{1}}实例您应该反转关系,并在ForeignKey模型中将FantasyPlayers字段添加到Player,然后您可以使用related_field访问Player列表来自FantasyPlayers实例的{1}}实例。

答案 1 :(得分:1)

这个解决方案怎么样? (我不确定ManyToManyField是最好的选择。)

class FantasyPlayer(models.Model):
    user = models.ForeignKey(User, unique=True)
    player = models.ForeignKey(Player)
    position = models.MultiSelectField(choices=POSITION_CHOICES, max_length=10)

# To get a list of players
user_fantasy_players = user.fantasyplayer_set.all()

它的一个缺点是无法使用limit_choices_to只允许在编辑Player时选择匹配位置FantasyPlayer(如您的示例所示),但这可以通过其他方式解决。从长远来看,拥有更优雅和理智的数据架构更为重要,IMO。