繁体   English   中英

Django - 多对多关系不是唯一的

[英]Django - ManyToMany relationship not unique


所以情况是:
我有一门课程 model 与学生 model 有多对多关系。 该课程还与一个模块 model 具有一对多的关系,因此一个课程有许多模块,但每个模块属于一个课程。

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

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

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)

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

解决此问题的方法是重组 model。

  1. 从模块 model 中删除完整的 boolean 字段。

  2. 创建另一个 model completed_modules 将具有与学生的一对一字段、与课程的一对一字段以及与模块的一对一字段,如下所示:

     class CompletedModules(models.Model): module = models. ForeignKey(Module, on_delete=models.CASCADE) course = models.ForeignKey(Course, on_delete=models.CASCADE) user = models.ForeignKey(Student, on_delete=models.CASCADE)

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

您需要重写已完成的 function 以实现此插入操作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM