In Django ORM, A "Student - Course" Model design

I would like to design a model for an online private school in Django. It focuses on relation among Students, Tutors and Courses.

The most important factor that should be considered is that Students can add and Tutors can create courses.

I'd like to extend built-in Djano's "User" and extend its functionality.

I have designed a very draft model like this:

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)

First of all: is it a correct approach? I'd like to have User, so I can use it in View and Template layers.

Second, how can I query that which student has got which courses?

Thank you beforehand ..

Answers


Rather than have a Student and Tutor model I would look at using the user profiles supported by Django. Also the auth module has a fairly complete permissions model, that you could use instead of creating your own system to allow only some users to create courses.


As @cberner says, you should look into user profiles. At the end of the day you want both the students and tutors be true-blue Users so you can access them from the request, after they're logged in.

That being said, there's still some merit in having separate models, as long as those are proxy models. You can think of proxy models as a type of alias. They can't add additional fields to the database, but they can have their own unique methods, managers, etc. For example:

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

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

That's a very basic example, but it's meant to illustrate that even though this is still a User as far as the database is concerned, you can override and add methods that make it unique in its own right.

Of course, though, you'll need some way to differentiate a Student from a Tutor and even a regular old User. I find groups to be the best way to accomplish this for User proxies. For example, you can create "Student" and "Tutor" groups and then any user assigned to the "Student" group, for example, can be obtained through the Student model.

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)

That assures that any time you create a Student, it's automatically added to the "Student" group, and if you retrieve objects with Student (e.g. Student.objects.all()), you only get Users that belong to the "Student" group.

Because these are separate models, you can also reference them individually in the admin, so you can have a separate changelist and change form for a Student, for a Tutor, and for a regular User, if you want.

Assigning them to groups also makes it very easy to restrict parts of the admin. For example, since only Tutors should be able to create, change or delete courses you can add the following methods to your 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()

And only superusers or members of the "Tutor" group will be able to add a brand new or change or delete an existing course.


Need Your Help

Finding the number of non-blank columns in an Excel sheet using VBA

excel vba excel-vba

How do I find the number of used columns in an Excel sheet using VBA?

Python Spyder reset

python spyder

I was using python(x,y), which came with Spyder. Yesterday, Spyder crashed I can't figure it out how to fix it. I uninstalled python(x,y) and reinstalled, still the same problem.