把我的脑袋缠在外键上

时间:2013-03-21 22:58:30

标签: python django

我已经发布了一个关于同一个项目的问题,所以希望这并不烦人,但我确实需要确保我知道我在使用ForeignKey做什么,所以我不(a)避免它或(b)养成坏习惯。

我正在制作一个锻炼游戏,每个用户都有自己的帐户。游戏分为不同的“周”,每周都有各种基准,用户必须满足才能继续下周。以下是我对周数进行建模的示例:

class WeekOne(models.Model):
    # Required benchmarks for given exercises 
    squatBenchmark = 1000
    lungBenchmark = 250
    stairDaysCountBenchmark = 3
    squats = models.PositiveIntegerField()
    lunges = models.PositiveIntegerField()
    skipStairs = models.BooleanField()
    stairDaysCount = models.PositiveSmallIntegerField()
    # Set to true if benchmarks reached. 
    weekOneComplete = models.BooleanField()

现在,我希望每个用户都有自己的深蹲,弓步,跳过等等字段,所以我认为这样做的方法是在UserProfile中创建一个ForeignKey字段(User的扩展名)模型,像这样:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    weekOne = models.ForeignKey(WeekOne)

    def checkUpdates(self):
        if self.WeekOne.squats >= WeekOne.squatBenchmark and \
            self.WeekOne.lunges >= WeekOne.lungBenchmark and \
            self.WeekOne.stairsDayCount >= WeekOne.stairDaysCountBenchmark and \
            self.WeekOne.skipStairs:
                self.WeekOne.weekOneComplete = True
                self.save()
                self.WeekOne.save()

这似乎不起作用。我创建了一个视图,我将此模型的上下文传递给模板,如下所示:

def workout1(request):
    user = UserProfile(user=request.user)
    template = "workout1.html"
    context = {'user': user}
    return render(request, template, context)

但是当我尝试在模板中显示user.weekOne.squats时,我收到了一个DoesNotExist错误。此外,我希望能够显示WeekOne“静态”变量,如squatBenchmark,但我的Django模板中也无法识别WeekOne.squats。任何人都可以给我任何关于我是否正确使用ForeignKeys以及在我的视图和模板中尝试使用它们时出错的地方的任何见解?

1 个答案:

答案 0 :(得分:1)

您所指的任何地方self.WeekOne我认为您的意思是self.weekOne

weekOne是实例变量。 UserProfile实例没有WeekOne这样的属性。

标准Python命名约定会建议您使用week_one作为属性名称。重写checkUpdates给你......

class UserProfile(models.Model):

user = models.OneToOneField(User) week_one = models.ForeignKey(WeekOne)

    def check_updates(self):
        if (self.week_one.squats >= WeekOne.squatBenchmark and
            self.week_one.lunges >= WeekOne.lungBenchmark and
            self.week_one.stairs_day_count >= WeekOne.stair_days_count_benchmark and
            self.week_one.skip_stairs):
                self.week_one.week_one_complete = True
                self.save()
                self.week_one.save()

在您的视图代码中,您正在创建一个UserProfile对象,但您永远不会保存它。您可能不希望每次请求进入时都创建新的用户配置文件。 Django有一些自动创建userprofile的内置机制。此外,您永远不会创建WeekOne实例。像

这样的东西
profile = UserProfile(user=request.user)
week_one = WeekOne()
week_one.save()
profile.week_one = week_one
profile.save()

您正在为用户创建配置文件,创建WeekOne实例,将其添加到配置文件,并将它们保存到数据库中。