【问题标题】:(beginner) First Django Web App - models.py(初学者)第一个 Django Web App - models.py
【发布时间】:2016-04-17 20:18:27
【问题描述】:

[在完成 Django 官方教程和 Django Girls 教程之后],我正在启动我的第一个 Django 网络应用程序。我在设置模型时遇到了一些麻烦。我现在有一些东西可以工作,但我觉得它效率很低,我宁愿在继续之前学习正确的方法..

开始 - 在学习一门新的编程语言时,很多人(在互联网上)建议选择一个您喜欢的主题/爱好并以此为基础创建一个项目。我非常喜欢运动,想重新创建一个虚拟记分牌,类似于 ESPN 或任何其他体育网站。

我的 models.py 目前看起来像这样 -

class Game(models.Model):
    # start_time = models.DateTimeField()
    today = models.DateField(default=date.today)
    game_id = models.AutoField(primary_key=True)
    game_outcome = models.CharField(max_length=8)
    game_quarter = models.CharField(max_length=1)
    game_clock = models.PositiveSmallIntegerField()
    away_team_id = models.CharField(max_length=3)
    away_team_class = models.CharField(max_length=3)
    away_team_city = models.CharField(max_length=13)
    away_team_name = models.CharField(max_length=12)
    away_team_score = models.PositiveSmallIntegerField()
    home_team_id = models.CharField(max_length=3)
    home_team_class = models.CharField(max_length=3)
    home_team_city = models.CharField(max_length=13)
    home_team_name = models.CharField(max_length=12)
    home_team_score = models.PositiveSmallIntegerField()

但我觉得这是太多的变量,而不是正确的方法。我也尝试过这样的事情......

class Day(models.Model):
    today = models.DateField(default=date.today)

class Game(models.Model):
    game_id = models.AutoField(primary_key=True)
    game_outcome = models.CharField(max_length=8)
    game_quarter = models.CharField(max_length=1)
    game_clock = models.PositiveSmallIntegerField()
    away_team_id = models.CharField(max_length=3)
    away_team_score = models.PositiveSmallIntegerField()
    home_team_id = models.CharField(max_length=3)
    home_team_score = models.PositiveSmallIntegerField()

class Team(models.Model):
    team_id = models.ForeignKey('Team')
    team_class = models.CharField(max_length=3)
    team_city = models.CharField(max_length=13)
    team_name = models.CharField(max_length=12)

每天有 0 到 xx 场比赛。比每场比赛都有:结果(空或'FINAL'),当前季度('1'或空),当前时钟('00:00'或空),客队('CHA'),客场得分('99' )、主队 ('TOR') 和主场比分 ('102')。然后我会拿团队ID并将其与班级团队进行比较。每个团队都有一个班级(对于 css:'tor')、一个城市('Toronto')和全名('Raptors')。

它仍然没有留在我的脑海中。我可以在 python shell 中获取所有信息并输出到我的 html/css,但我觉得它效率低下。此外,每一天都有自己的 html 页面(类似于 website.com/nba/scores/20150112/),里面装满了当天的所有比赛。

对不起,如果这太初学者了,不能问;我花了很多时间寻找答案,最后决定在 stackoverlow 上发帖(我的第一个问题)。

任何信息或建议将不胜感激。

【问题讨论】:

    标签: python django dynamic webpage


    【解决方案1】:

    我认为您的模型方法的总体思路已经足够好了。尽管如此,我还是鼓励你通过Django's ORM relationships documentation。如果你想使用字符串作为主键也没关系,但是通过使用the proper model field 让 Django 的 ORM 知道这一点。如果您使用主键和外键(关系),您的 dbms 将在必要字段上创建索引,从而提高查询效率。让我知道这是否有帮助!祝你的项目好运!

    更新:

    应该是这样的:

    class Day(models.Model):
        today = models.DateField(default=date.today)
    
    class Game(models.Model):
        game_outcome    = models.CharField(max_length=8)
        game_quarter    = models.CharField(max_length=1)
        game_clock      = models.PositiveSmallIntegerField()
        day = models.ForeignKey(Day, on_delete=models.CASCADE)
        away_team       = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='away_team')
        away_team_score = models.PositiveSmallIntegerField()
        home_team       = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='home_team')
        home_team_score = models.PositiveSmallIntegerField()
    
    class Team(models.Model):
        team_class = models.CharField(max_length=3)
        team_city = models.CharField(max_length=13)
        team_name = models.CharField(max_length=12)
    

    请注意,我省略了所有 id 字段,因为 django 将使用一个自动创建的字段,其行为与 AutoField 相同。另请注意,由于Game 有两个对同一类(Team)的引用,因此有必要提供额外的参数related_name。在django docs about related_name了解更多信息。

    这样,你可以做类似的事情

    game = Game.objects.find(1)
    away_team_name = game.away_team.team_name
    

    您可以在away_team 变量中访问关联的Team 类。根本不需要打电话给away_team_id

    【讨论】:

    • 太棒了,谢谢!因此,如果我在阅读文档后理解正确,这将是设置......? class Day class Game... 与 Day 具有多对一关系(10 场比赛,只有 1 天) class Team... 与 Game 具有一对一关系(每个 home_team_id 和 away_team_id 都是直接一对一的) - 一个与他们的 team_name、team_city 和 team_class 在类 Team 本身中的关系)
    • @asapzacy:从概念上讲,在Game 类中,Team 的外键也是多对一的关系,因为一个Team 可以参与许多Games。检查更新
    【解决方案2】:

    首先,您需要了解使用的 ForeignKey 越多,您对数据库的负载就越大。但它也很大程度上取决于views.py 代码。其次,如果您使用 ForeignKey,则不需要使用 team_id 作为字段名称。只需提及类名,它就会自动为该字段创建一个_id

    看下面的代码:

    class Game(models.Model):
        start_time = models.DateTimeField()
        today = models.DateField(default=date.today)
        game_id = models.AutoField(primary_key=True) # You don't need this line, an id field is created for EVERY model class even if you don't specify it.
        game_outcome = models.CharField(max_length=8)
        game_quarter = models.CharField(max_length=1)
        game_clock = models.PositiveSmallIntegerField()
        away_team = models.ForeignKey('Team')
        home_team = models.ForeignKey('Team')
    
    class Team(models.Model):
        team_class = models.CharField(max_length=3)
        city = models.CharField(max_length=13)
        name = models.CharField(max_length=12)
        score = models.PositiveSmallIntegerField()
    

    您可以看到我创建了另一个名为 Team 的类,并在您原来的 Game 类中重复的内容上放置了四个字段。然后我用ForeignKeyTeam 类连接到Game 类。如果您安装 SQLiteBrowser 并检查数据库文件,那么您将看到 away_team 字段实际上是数据库中的 away_team_id 字段,因为 Django 负责处理。您不需要创建id 字段,只需使用ForeignKeyManyToManyField 等关系。我想不到这是我唯一可以建议的。

    从这个项目的范围来看,你不会对关系太多的数据库施加太大的压力,所以现在不用担心。就是这样。如果您有任何更具体的问题,您可以提出。干杯! :)

    附:我不确定您的项目详细信息,因此请使用您认为合适的任何关系,无论是一对一、多对一还是多对多等。阅读文档以获取更多详细信息。 :)

    【讨论】:

      猜你喜欢
      • 2014-04-25
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 2010-11-08
      相关资源
      最近更新 更多