【问题标题】:Django Models Design: Solo-Player OR Team with players in GameDjango 模型设计:单人游戏或与游戏中的玩家组队
【发布时间】:2021-11-03 07:54:24
【问题描述】:

我正在为一个游戏设计一个基于 Django 的网络界面,该游戏既可以单人玩,也可以作为团队玩。游戏是基于积分的;达到设定点数的第一方获胜。为了以后的统计和显示,点有一个时间戳。

我的问题:如何将两个Players 或两个Teams 合为一个Game?我的模型现在看起来像这样:

from django.db import models

# Create your models here.

class Player(models.Model):
    slug = models.SlugField(unique=True)    # will be autogenerated when inserting new Instance
    name = models.CharField(max_length=100)
    wins = models.IntegerField()
    losses = models.IntegerField()

    picture = models.ImageField(upload_to='images/player_pics')

    # games_played = wins + losses 

    def __str__(self):
        return self.name

class Team(models.Model):
    slug = models.SlugField(unique=True)
    name = models.CharField(max_length=100)
    players = models.ManyToManyField(Player)
    
    wins = models.IntegerField()    # from here on seems redundant to Player class
    losses = models.IntegerField() 

    picture = models.ImageField(upload_to='images/team_pics')

    # games_played = wins + losses 

    def __str__(self):
        return self.name


class Point(models.Model):
    val = models.IntegerField()
    timestamp = models.DateTimeField()


class Game(models.Model):
    slug = models.SlugField(unique=True)
    timestamp = models.DateTimeField()
    players = models.ManyToManyField(Player) # here should be either Team or Player
    points = models.ManyToManyField(Point)

我的想法是实现另一个类,例如 GameParty,它可以是 PlayerTeam,但同样的问题也适用。胜负之类的冗余字段也是我不喜欢的。

【问题讨论】:

    标签: python django sqlite django-models


    【解决方案1】:

    您不需要硬编码赢、输和玩的游戏,因为您可以通过使用外键和多对多关系的查询来获取这些值(您也可以在模型中创建动态属性返回查询以避免重复)。改变你的模型:

    from django.db import models
    
    
    class Player(models.Model):
        slug = models.SlugField(unique=True)
        name = models.CharField(max_length=100)
        picture = models.ImageField(upload_to='images/player_pics')
    
        def __str__(self):
            return self.name
    
    class Team(models.Model):
        slug = models.SlugField(unique=True)
        name = models.CharField(max_length=100)
        players = models.ManyToManyField(Player)
        picture = models.ImageField(upload_to='images/team_pics')
    
        def __str__(self):
            return self.name
    
    
    class Point(models.Model):
        player = models.ForeignKey(Player, on_delete=models.PROTECT, related_name='points') # You need to associate the player with the point
        val = models.IntegerField()
        timestamp = models.DateTimeField()
    
    
    class Game(models.Model):
        slug = models.SlugField(unique=True)
        timestamp = models.DateTimeField()
        players = models.ManyToManyField(Player, related_name='games')
        points = models.ManyToManyField(Point)
    

    现在例如要获取玩家玩过的游戏,您可以编写以下查询:

    player = Player.objects.get(id=1)
    games_played = player.games.count()
    

    或使用动态属性(此属性未插入到数据库中,但在每次调用时都会对其进行评估,因此您无需更新它):

    class Player(models.Model):
        # Your fields and methods
        @property
        def games_played(self):
            return self.games.count()
    

    要编写查询,请参考documentation。如果您还想将团队与游戏相关联,您可以创建一个额外的表格或使用generic relation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多