Django - 正在为用户推荐使用代理模型吗?

时间:2011-03-08 14:18:54

标签: django django-models django-admin

目前,我正在使用一些代理模型来区分管理网站中的不同用户。

class TeacherProxy(User):
    class Meta:
        proxy=True
        app_label = 'auth'
        verbose_name = 'Teacher'
        verbose_name_plural = 'Teachers'

class TeacherAdmin(admin.ModelAdmin):
    #inlines = [TeacherClassInline]
    def queryset(self,request):
        return User.objects.filter(groups__name='Teachers')
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "groups":
            qs = Group.objects.filter(name='Teachers')
            kwargs["queryset"] = qs
            kwargs["initial"] = qs
        return super(TeacherAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

admin.site.unregister(User)
admin.site.register(TeacherProxy,TeacherAdmin)

然而,我意识到如果我使用这种方法会破坏一些事情:

  1. 不允许我添加 用于外键的tabularInlines 关系,因为Django 抱怨没有外键 for userproxy。
  2. 网址搞砸了。 Django会 寄存器 http://abc.com/admin/auth/teacherproxy/ 代替 http://abc.com/admin/auth/user/ 和Django找不到老师 对象。
  3. 对此有何评论?

2 个答案:

答案 0 :(得分:2)

通常,Django喜欢通过添加用户配置文件来扩展用户模型。以下是他们如何执行此操作的文档:

http://docs.djangoproject.com/en/dev/topics/auth/#auth-profiles

然后,您可以在每个用户的个人资料中添加一个字段,以指定他们是否是教师。

就个人而言,我发现使用Django更容易,就像文档建议你使用Django一样,因为你知道一切正常。此外,如果将来出现问题,将更容易找到其他人的支持。因此,我会添加一个配置文件类来按照他们的说法扩展用户模型。

答案 1 :(得分:1)

Django支持将具有外键的模型内联到父类。看到这个bug: https://code.djangoproject.com/ticket/7918

在Django模型继承之上,您使用的是一个代理模型,它应该是它引用的模型的透明直通。我还发现它不能正常运行并且抱怨没有合适型号的外键。

一种解决方案是使用Django通用关系: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#using-generic-relations-as-an-inline

您可以将以下字段添加到模型中,而不是将外键添加到父类:

content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')

Django现在可以为您的应用中的任何其他模型提供外键。它实际上存储了它所指向的对象的id以及对象的类型(content_type)。请注意,每次遵循foreignkey关系时,django必须在content_types表中进行额外查找,以确定泛型关系实际指向的模型。