2013-03-21 2 views
0

Я уже написал один вопрос о том же проекте, так что, надеюсь, это не раздражает, но мне действительно нужно убедиться, что я знаю, что я делаю с ForeignKey, поэтому я не (а) избегать этого или (б) развивать вредные привычки.Обертывание моей головы вокруг внешних ключей

Я работаю над игрой для тренировки, где каждый пользователь имеет свою собственную учетную запись. Игра делится на различные «недели», каждая неделя имеет различные контрольные показатели, которые пользователь должен выполнить, прежде чем сможет перейти к следующей неделе. Вот пример того, как я модель недели:

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() 

Теперь я хочу, чтобы каждый пользователь должен иметь свои собственные приседания, выпады, skipStairs и т.д. поле, поэтому я думал, что способ сделать это было бы создать

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() 

Это, кажется, не работает: а ForeignKey поле в UserProfile (расширение пользователя) модель, как и так. Я создал представление, где я прохожу контекст этой модели в шаблон, например, так:

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, но WeekOne.squats не распознается в моем шаблоне Django. Может ли кто-нибудь дать мне представление о том, правильно ли я использую ForeignKeys и где я ошибаюсь, пытаясь использовать их в своих взглядах и шаблонах?

+0

Может ли пользователь иметь более одной недели? Если нет, возможно, вы должны изменить 'ForeignKey' на' OneToOneField' или использовать его как 'user.weekOne_set [0] .squats', но я не уверен в синтаксисе. – EralpB

+0

Нет, у WeekOne есть константы в качестве эталонных тестов, но такие вещи, как поля для приседаний, выпадений, skipStairs, изменяются в зависимости от того, какие данные вводит пользователь. – user1427661

+0

вы вчера не читали мой ответ на свой вопрос. Я рассказываю о том, как получить доступ к данным для пользователя. Вы полностью изменяете check_updates. Ваши последующие инструкции. – catherine

ответ

1

Везде вы смотрите self.WeekOne Я думаю, вы смысл обратиться к self.weekOne

weekOne является переменной экземпляра. У экземпляров UserProfile нет таких атрибутов WeekOne.

Стандартные соглашения об именах Python предполагают, что вы используете week_one в качестве имени атрибута. Переписывание checkUpdates для вас ...

class UserProfile(models.Model): 

пользователя = models.OneToOneField (Пользователь) 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, добавив его в профиль, и сохранение их обоих в базу данных.

+0

Хороший улов, спасибо. Но я все еще сталкиваюсь с основной проблемой, с которой я не могу пройти, то есть когда я объявляю 'user = UserProfile (user = request.user)', передаю пользователя в качестве контекста в свой шаблон и вызываю 'user .week_one.squats' или 'user.squats', я либо получаю ошибку DoNotExist, либо на странице не отображаются данные приседа. Кроме того, действительно ли соглашения об именах Python действительно требуют использования подчеркиваний во всех именах переменных или только когда имя относится к классу? Я видел тонны кода, который использует camelCase в качестве основного соглашения, хотя Django, похоже, предпочитает подчеркивания. – user1427661

+0

Yup, вы можете найти старый код (я смотрю на вас, скрученный), который использует camelCase. Но вы не найдете никакого нового кода. Подчеркиваются переменные/атрибуты. Названия классов - CamelCase. Pep8 все выложил: http://www.python.org/dev/peps/pep-0008/#prescriptive-naming-conventions. Поговорите, я отредактирую свой ответ на оставшиеся ваши вопросы. – aychedee

+0

О, m не означает быть douchey о условностях стиля. У Python есть действительно сильные стильные условные обозначения, и каждый использует их, чтобы вы могли просто прыгнуть на борт фургона. – aychedee

Смежные вопросы