2014-05-06 42 views
0

我有一个使用像这样的外键移动的游戏模式:我的模型在Django中的设计?

class Moves(models.Model): 
    player1 = [] 
    player2 = [] 

    def make_move(self, a_int, b_int, c_bool):   
    if c_bool: 
     self.player1.append(a_int) 
    else: 
     self.player2.append(b_int) 

    #...irrelevant functions 

class Game(models.Model): 
    #...irrelevant variables 
    moves = models.ForeignKey(Moves) 

所以我想每场比赛有一组唯一的举动。 Moves存储在player1和player2的列表中。

在我的测试中,我做这样的事情

所以......

class MakeMoveTestCase(TestCase):  
    def test_make_move(self): 
     g = Game() 
     g.moves.make_move(3, 0, False) #####throws error here 
     g.moves.make_move(4, 0, False) 

,并得到这个错误:

TypeError: int() argument must be a string or a number, not 'list'

我需要帮助摆脱这种错误的。另外,如果你有更好的设计,我希望看到它。

回答

2

而不是向您展示如何摆脱这种错误的,我会尽量解释什么你的设计是错误的。

首先,您定义的Moves类作为模型没有意义。这是因为在那里没有定义模型字段。如果要使用此模型存储数据,则必须定义属于field classes的实例。

所以你可能要重新命名MovesMove(因为它代表一个单一的举动),并重新定义如下:

from django.db import models 
from django.utils.translation import ugettext as _ 

class Move(models.Model): 
    PLAYER_1, PLAYER_2 = 1, 2 
    PLAYERS = (
     (PLAYER_1, _('Player 1')), 
     (PLAYER_2, _('Player 2')) 
    ) 

    game = models.ForeignKey(Game, related_name='moves') 
    player = models.IntegerField(choices=PLAYERS) 
    x = models.IntegerField() 
    y = models.IntegerField() 

现在,如果你想创建一个游戏,此举并添加游戏,那么你可以写这样的事情:

game = Game.objects.create(...) 
move = Move.objects.create(game=game, x=1, y=5, player=Move.PLAYER_2) 
+0

此举代表了我创建的一个名为“点”的点。所以像这样的东西。对于玩家1而言[点(x = 4,y = 0),点(x = 4,y = 1),点(x = 4,y = 2),点(x = 4,y = 3)等等 – Ryan

+0

我知道我在创建一个没有现场类的模型,因此我怀疑我的设计。我怎么能做得更好? – Ryan

+0

我明白你在说什么了,但是我会如何处理2名球员呢? – Ryan

1

你应该在游戏实例之前测试创建移至实例,并链接到游戏之前调用它的方法:

class MakeMoveTestCase(TestCase):  
    def test_make_move(self): 
     moves = Moves() 
     game = Game(moves=moves) 
+0

+1,删除了即时错误。谢谢。 – Ryan

2

如果你在Django执行,并且要保持一个良好的模型 - 视图 - 模板的区别,那么你应该考虑改变你的Moves模型。模型只能表示数据,因此make_move应该移动到视图或其他支持类。你的Moves模型中的玩家似乎也应该是一个单独的职业,因为玩家理论上可以在多个游戏中进行动作等。换句话说,将玩家与动作分开。

此外,我同意@piotrekw,Moves应该成为Move,应该只代表一个举动。每一步都应该链接到Player,该链接使其成为外键字段,并且链接到它所属的Game

class Player(models.Model): 
    pass 

class Game(models.Model): 
    player1 = models.ForeignKeyField(Player._id) 

class Move(models.Model): 
    game = models.ForeignKeyField(Game._id) 
    player = models.ForeignKeyField(Player._id) 
    a_int = models.IntegerField() 
    b_int = models.IntegerField() 

从这里,实际上增加了Move应该遵循标准的Django练习,你可以在教程中找到here