Django-ManyToMany关系不唯一

问题描述 投票:0回答:1

因此,情况是:我有一个课程模型与一个学生模型有很多联系。该课程也与模块模型具有一对多的关系,因此一门课程具有许多模块,但是每个模块都属于一个课程。

在我的模块上,我指定了一个名为complete的布尔字段,以便能够计算出该学生完成了该课程的模块数量。主要问题是:当学生完成某个模块后,它将被标记为永远完成。换句话说,当另一个用户注册相同的课程时,他会发现另一个用户留下的模块的完成状态。

我希望在学生注册课程时初始化每个模块,但也希望仅为该学生保存模块而不在全局范围内保存更改,这就像在新用户注册时制作课程的初始化副本一样。并将其记录保存在此副本上,而不是保存在数据库中的实际课程模型上。谢谢,这是代码:

class Student(models.Model):
    user        = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
    full_name   = models.CharField(max_length=200, null=True, blank=True)
    age         = models.PositiveIntegerField(null=True, blank=True)
    email       = models.CharField(max_length=200, null=True, blank=True)
    phone       = models.CharField(max_length=20, null=True, blank=True)
    about       = models.TextField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=False, null=True, blank=True)


class Course(models.Model):
    owner = models.ForeignKey(User, related_name='courses_created',help_text=_('owner') ,on_delete=models.CASCADE)
    subject = models.ForeignKey(Subject, related_name='courses',help_text=_('subject') ,on_delete=models.CASCADE)
    title = models.CharField(max_length=200,help_text=_('title'))
    slug = models.SlugField(max_length=200, help_text=_('slug') ,unique=True, allow_unicode=True)
    overview = models.TextField(help_text=_('overview'))
    created = models.DateTimeField(auto_now_add=True)
    thumbnail = models.ImageField(upload_to='images', null=True, blank=True)
    students = models.ManyToManyField(Student, related_name='courses_joined',help_text=_('students'), blank=True)

    def completion_rate(self):
        sum = 0
        for m in self.modules.all():
            if m.completed:
                sum +=1
        rate = int((sum / self.modules.count()) * 100)
        return rate


 class Module(models.Model):
    course = models.ForeignKey(Course, related_name='modules',help_text=_('course') ,on_delete=models.CASCADE)
    title = models.CharField(max_length=200 )
    description = models.TextField(blank=True)
    order = OrderField(blank=True, for_fields=['course'])
    completed = models.BooleanField(default=False, null=True)

以及完成模块的视图:

def complete(request, m_id, c_id):
    mod = get_object_or_404(Module, id=m_id)
    course = get_object_or_404(Course, id=c_id)
    mod.completed = True
    mod.save()
    return redirect('student_course_detail_module', course.id ,mod.id)
python django many-to-many django-3.0
1个回答
0
投票

这是一个逻辑问题。您正在向模块中添加一个布尔字段,该字段一旦由单个学生设置,将为所有其他登录的学生保持设置。

解决方案是重构模型。

  1. 从模块模型中删除完成的布尔字段。

  2. 创建另一个模型completed_modules,其中将具有与学生的一对一字段,具有课程的一对一字段以及具有模块的一对一字段,例如:

  3. class CompletedModules(models.Model): 模块=型号。 ForeignKey(模块,on_delete = models.CASCADE) 课程=模型.ForeignKey(课程,on_delete =模型.CASCADE) user = models.ForeignKey(Student,on_delete = models.CASCADE)

    当给定的学生完成给定课程的给定模块时,您只需将其记录在此表中

您将需要重写完成的功能才能执行此插入操作

© www.soinside.com 2019 - 2024. All rights reserved.