2012-06-13 30 views
1

我想設計一個Django在線私立學校的模型。它側重於Students,TutorsCourses之間的關係。在Django ORM中,「學生 - 課程」模型設計

應該考慮的最重要的因素是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) 

首先:它是一個正確的做法?我想要用戶,所以我可以在視圖和模板圖層中使用它。

其次,我如何查詢哪個學生有哪些課程?

謝謝您事先..

回答

1

不是有StudentTutor模型我想看看使用Django支持的user profiles。此外,驗證模塊還有一個相當完整的模型,您可以使用該模型而不是創建自己的系統來僅允許某些用戶創建課程。

+0

謝謝cberner。你是否推薦使用Proxy Model?除了普通的Django User字段外,我還需要添加一些字段給Student和Tutors。 – Soask

3

正如@cberner所說,您應該查看用戶配置文件。在這一天結束時,您希望學生和導師都是真實的藍色User s,因此您可以在登錄後從請求中訪問它們。

這就是說,單獨分開還有一些優點型號,只要是代理型號。您可以將代理模型視爲一種別名。他們不能添加其他字段到數據庫中,但他們可以有自己獨特的方法,管理人員等。例如:

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

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

這是一個非常簡單的例子,但它意在說明,儘管這是就數據庫而言仍然是User,您可以覆蓋並添加使其獨一無二的方法。

當然,您需要一些方法來區分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 s表示屬於「學生「小組。

因爲這些都是獨立的模型,你也可以單獨引用它們的管理,這樣你就可以有一個單獨的變更表和變更形式爲Student,爲Tutor,並定期User,如果你想要的。

將它們分配給組也可以很容易地限制管理員的部分。例如,由於只有Tutor S的關係能夠創建,更改或刪除課程,你可以在下面的方法添加到您的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() 

而且只有超級用戶或「家庭教師」組的成員將能夠添加全新的或更改或刪除現有課程。

+0

這是一個令人興奮的反應..一個大五高.. 但我仍然想知道如果要訪問學生的名字,我應該查詢「Student.course」或「User.course」? 特別是,我應該通過ManyToManyField(直接或通過「表」)將課程鏈接到學生,並且對於導師也是如此。 – Soask

+0

沒關係。 'Student'只是'User'的別名,所以不管你的實例是'Student'還是'User','instance.course'都會得到你想要的。 「課程」應該是一種M2M關係(學生/導師有很多課程和課程有很多學生,也許有導師)。然而,你的'ManyToManyField'應該在'Course'上,它應該指向'User'。這涵蓋了學生和導師。 –

+0

太好了,但考慮到我們想把學生連接到學校。我應該爲學生添加一些額外的字段。那麼,我也必須跟蹤學生的活動!所以我必須將學生鏈接到其他表格。 將所有這些與代理模型結合是否可行? – Soask