在Django ORM中,一个“学生 - 课程”模型设计

时间:2012-06-13 16:32:00

标签: database django django-models django-views pinax

我想为Django的在线私立学校设计一个模型。它侧重于StudentsTutorsCourses之间的关系。

应考虑的最重要因素是Students可以添加,Tutors可以创建课程。

我想扩展内置Djano的“用户”并扩展其功能。

我设计了一个这样的草案模型:

from django.db import models
from django.contrib.auth.models import User , Group
from django.utils.translation import ugettext as _


class Course(models.Model):
    name = models.CharField(max_length = 70)
    slug = models.SlugField()
    created = models.DateTimeField(auto_now = True)
    updated = models.DateTimeField(auto_now_add = True)
    description = models.TextField()
    student = models.ManyToManyField('Student' , null = True, blank = True, related_name = _('Student courses'))
    tutor = models.ManyToManyField('Tutor' , null = True, blank = True , related_name = _('Tutor courses'))


    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name = ('course')
        verbose_name_plural = ('courses')


class Student(models.Model):
    user = models.ForeignKey(User , blank = True)
    #photo = models.ImageField(_('photo'), upload_to='photos/', blank=True)



class Tutor(models.Model):
    user = models.ForeignKey(User , blank = True)
    #photo = models.ImageField(_('photo'), upload_to='photos/', blank=True)

首先:这是一种正确的方法吗?我想拥有User,所以我可以在View和Template层中使用它。

其次,我如何查询哪个学生有哪些课程?

先谢谢你..

2 个答案:

答案 0 :(得分:3)

正如@cberner所说,您应该查看用户个人资料。在一天结束时,您希望学生和导师都是真蓝User,这样您就可以在登录后从请求中访问它们。

话虽如此,只要那些是代理模型,拥有单独的模型仍然有一些优点。您可以将代理模型视为一种别名。他们无法向数据库添加其他字段,但他们可以拥有自己独特的方法,经理等。例如:

class Student(User):
    class Meta:
        proxy = True

    def __unicode__(self):
        return u'Student: %s' % super(Student, self).__unicode__()

这是一个非常基本的例子,但它的意思是说明即使数据库仍然是User,你也可以覆盖并添加使其独有的方法。 / p>

当然,您需要某种方法来区分StudentTutor甚至是常规的User。我发现组是User代理完成此操作的最佳方法。例如,您可以创建“学生”和“导师”组,然后分配给“学生”组的任何用户都可以通过Student模型获得。

class StudentManager(models.Manager):
    def get_query_set(self):
        return self.filter(groups__name='Student')

class Student(User):
    class Meta:
        proxy = True

    def save(self, *args, **kwargs):
        super(Student, self).save(*args, **kwargs)
        if not self.groups.filter(name='Student').exists():
            group, created = Group.objects.get_or_create('Student')
            self.groups.add(group)

这确保您在创建Student时,它会自动添加到“学生”组中,如果您使用Student检索对象(例如Student.objects.all()),则只能获得User属于“学生”群组。

由于这些是单独的模型,您还可以在管理员中单独引用它们,因此您可以为StudentTutor和常规{User创建单独的更改列表和更改表单{1}},如果你愿意的话。

将它们分配给组也可以很容易地限制部分管理员。例如,由于只有Tutor应该能够创建,更改或删除课程,因此您可以将以下方法添加到CourseAdmin

def has_add_permission(self, request):
    return request.user.is_superuser or request.user.groups.filter(name='Tutor').exists()

def has_change_permission(self, request, obj=None):
    return request.user.is_superuser or request.user.groups.filter(name='Tutor').exists()

def has_delete_permission(self, request, obj=None):
    return request.user.is_superuser or request.user.groups.filter(name='Tutor').exists()

只有超级用户或“Tutor”组的成员才能添加全新或更改或删除现有课程。

答案 1 :(得分:1)

我不会使用StudentTutor模型,而是使用Django支持的user profiles。此外,auth模块还有一个相当完整的permissions模型,您可以使用该模型而不是创建自己的系统,只允许一些用户创建课程。