Django - Общие отношения
У меня есть сайт с различными видами деятельности:
- Уроки ;
- Упражнения ;
- Викторины.
До сих пор каждый вид деятельности соответствует определенной Модели и таблице в базе данных. Я хотел бы создать упорядоченный путь через эти виды деятельности. Например:
- Урок 1
- затем Упражнение 1
- урок 2
- затем контрольная работа 1
- и т.д.
Я собираюсь создать модель с именем Activity, которая будет хранить следующие данные:
- Число: номер вида деятельности на пути ;
- Отношение "один-к-одному" к одному заданию (уроку, упражнению, контрольной работе и т.д.).
(1) Я видел, что Django предлагает GenericForeignKey для обработки отношений "многие-к-одному" к различным типам моделей, например, множество комментариев, связанных с одним уроком или одним упражнением. Есть ли что-то подобное для Generic OneToOne отношений?
(2) Я хотел бы отслеживать прогресс моих пользователей. Для этого я рассматриваю возможность создания отношения "многие-ко-многим" под названием "done_activities" в модели User и связать его с моделью Activity. Считаете ли вы, что это эффективный способ решения проблемы?
Я не уверен, что в этом случае вам понадобятся или нужны самореферентные поля. В качестве примера рассмотрим следующую структуру. Я не предлагаю ее "в камне" в качестве решения, а скорее для того, чтобы подстегнуть ваши собственные идеи о том, какое решение вам нужно. Обратите внимание, что для краткости я опускаю методы __str__ и т.п.:
ACTIVITY_TYPE = ['Lesson', 'Exercise', 'Quiz']
class Activity(models.Model):
activity_name = models.CharField(max_length=200, blank=True)
activity_type = models.CharField(max_length=100, choices=ACTIVITY_TYPE, blank=True, db_index=True)
activity_desc = models.CharField(max_length=200, blank=True) #description of the lesson, exercise, or quiz
class Program(models.Model):
program_name = models.CharField(max_length=200, blank=True, db_index=True)
description = models.Charfield(max_length=200, blank=True)
class ProgramActivity(models.Model):
program = models.ForeignKey(Program, on_delete=models.CASCADE, your args etc...)
activity = models.ForeignKey(Activity, on_delete=models.CASCADE, your args here etc...)
path_order = models.PositiveSmallIntegerField() # stores a number for the order in the program path
class UserProgram(models.Model):
student = models.ForeignKey(User, etc...) # FK to the user
program = models.ForeignKey(Program, etc...) # connects users to programs
progress = models.DecimalField(max_digits=5, decimal_places=2) # stores percentage of program completed (for example)
В этом сценарии схемы верно следующее:
Activityотслеживаются и хранятся вместе в одной таблице, организованные по типам, и каждый из них может иметь свое собственное описание.Programхранятся в собственной модели, и представляют собой именованный объект, который объединяет все составляющие их действия.ProgramActivityсвязывает действия с конкретными программами и позволяет вам установить порядок в пути для этой деятельности относительно программы , и легко изменить его, если потребуется. Вы можете легко запроситьactivities = ProgramActivity.objects.filter(program=some_program).order_by('path_order')и получить очень удобный список активностей программы.- Наконец, модель
UserProgramрегистрирует "зачисления" пользователя и прогресс в каждом из них, в данном примере, по проценту выполнения программы.
Это лишь один из возможных подходов. Например, вы можете захотеть создать таблицу типов деятельности вместо выпадающего списка, что может быть более надежным способом управления деятельностью во времени.