#django #django-models
#django #django-модели
Вопрос:
В настоящее время я застрял на том, как сделать следующее:
Я хочу отслеживать тренировки и видеть прогресс, достигнутый в выполнении упражнений.
У каждой тренировки есть название, вес тела, дата и упражнения.
Я хочу выбирать упражнения при добавлении тренировок (упражнения уже предварительно созданы с именем и некоторыми тегами), однако каждая тренировка отличается, то есть повторения, сеты и вес для упражнения каждый раз разные.
Я не уверен, как создать модель для этого.
Я добавил изображение простого дизайна, который я сделал, чтобы показать, что мне нужно
Надеюсь, кто-нибудь сможет мне помочь, я почти уверен, что это простое решение, однако мой мозг застрял в банкомате.
Ответ №1:
Прежде всего, я бы рекомендовал ознакомиться с документами по моделям Django, чтобы получить представление о том, что представляют модели и как они работают.
Чтобы ответить на ваш вопрос, я думаю, вы правильно определили всю информацию, необходимую для создания ваших моделей, поэтому давайте пройдемся по ним шаг за шагом.
Архитектура
Полезно сделать шаг назад и подумать о сущностях в вашем приложении. Определите, что они собой представляют, какими атрибутами они обладают и какие из этих атрибутов являются атомарными, т.Е. Не могут быть их собственной сущностью.
- Тренировка — Вы упомянули, что хотите отслеживать тренировки, каждая из которых имеет название, вес тела, дату и упражнения. Все эти атрибуты, за исключением упражнений, кажутся атомарными, поскольку они могут быть представлены с помощью основных типов данных (строки, числа с плавающей точкой, даты и т. Д.). Более того, в одной тренировке может быть много упражнений, указывающих на то, что нам нужно абстрагировать ее в свою собственную сущность.
- Упражнение — вы определили, что упражнения предварительно настроены и должны иметь название и теги. Имя — это то, что мы можем представить с помощью строки, однако одно упражнение может иметь несколько тегов, что означает, что оно не является атомарным (имеет отношение «один ко многим«). Это означает, что нам нужно извлечь его в его собственную сущность.
- Тег — из того, что вы сказали, у тега просто есть один атрибут, который является именем, которое может быть представлено строкой. Один тег может принадлежать многим упражнениям.
Вам может быть интересно, где мы храним данные о повторениях, подходах и весе для каждого упражнения в каждой тренировке. На самом деле для этого потребуется дополнительная сущность, которая хранит отношения «многие ко многим» между упражнениями и тренировками. Давайте назовем эту тренировку-упражнение.
С помощью этой информации мы могли бы нарисовать диаграмму отношений сущностей как таковую:
Это дает нам то, что нам нужно, чтобы начать создавать модели Django.
Модели
Давайте начнем с сущностей Exercise
и Tag
. Мы можем просто перевести их непосредственно в модели Django:
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=200)
class Exercise(models.Model):
name = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag)
Здесь мы создали две модели и указали связь «многие ко многим» между Exercise
и Tag
. Это означает, что у Exercise
объекта может быть много Tag
объектов, например, вы можете вызвать exercise.tags.all()
, чтобы получить все теги для данного Exercise
объекта.
Сложная часть возникает, когда мы создаем Workout-Exercise
сущность. Когда мы используем ManyToManyField в Django, он обычно автоматически создает модель / таблицу сопоставления, которую мы не видим. Однако в случае, когда мы хотим сохранить дополнительную информацию об этих отношениях (как мы делаем в нашем примере использования), мы должны использовать сквозную модель.
В этой модели мы должны определить два внешних ключа для моделей, которые мы связываем, а также типы данных для дополнительных полевых данных, которые мы хотим сохранить. В этом случае внешними ключами являются Workout
and Exercise
, а дополнительными данными являются reps
sets
and weight
. Поэтому определения моделей могут выглядеть следующим образом:
class WorkoutExercise(models.Model):
workout = models.ForeignKey(
'Workout',
on_delete=models.CASCADE,
)
exercise = models.ForeignKey(
Exercise,
on_delete=models.CASCADE,
)
reps = models.IntegerField()
sets = models.IntegerField()
weight = models.DecimalField(max_digits=5, decimal_places=2)
class Workout(models.Model):
name = models.CharField(max_length=200)
body_weight = models.DecimalField(max_digits=5, decimal_places=2)
date = models.DateTimeField(auto_now_add=True)
exercises = models.ManyToManyField(
Exercise,
through=WorkoutExercise
)
Если вас смущает какой-либо из рекомендованных мной вариантов выбора типа данных модели, пожалуйста, ознакомьтесь с документами Django model docs .
С помощью этой настройки вы должны иметь возможность получать доступ и вставлять все необходимые вам данные. Если вам нужна дополнительная информация о том, как получить доступ к любым данным взаимосвязи «многие ко многим», пожалуйста, ознакомьтесь с документами Django many-to-many .
Источники