Django:访问抽象模型的子类

Django:访问抽象模型的子类,django,inheritance,abstract-class,Django,Inheritance,Abstract Class,我从一个基类继承了几个用户配置文件模型,如下所示: class BaseProfile(models.Model): user = models.ForeignKey(User) name = models.CharField(max_length=100) ... class Meta: abstract = True class DoctorProfile(BaseProfile): license_no = models.CharF

我从一个基类继承了几个用户配置文件模型,如下所示:

class BaseProfile(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=100)
    ...
    class Meta:
        abstract = True

class DoctorProfile(BaseProfile):
    license_no = models.CharField(max_length=10)
    ...

class PharmacistProfile(BaseProfile):
    pass
if user.doctorprofile_set.all().count() == 1:
    return user.doctorprofile_set.all()[0]
elif user.pharmacistprofile_set.all().count() == 1:
    return user.pharmacistprofile_set.all()[0]
...
当我有一个用户实例时,我希望获得他们的配置文件

我不想一个接一个地检查用户是否有个人资料,比如:

class BaseProfile(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=100)
    ...
    class Meta:
        abstract = True

class DoctorProfile(BaseProfile):
    license_no = models.CharField(max_length=10)
    ...

class PharmacistProfile(BaseProfile):
    pass
if user.doctorprofile_set.all().count() == 1:
    return user.doctorprofile_set.all()[0]
elif user.pharmacistprofile_set.all().count() == 1:
    return user.pharmacistprofile_set.all()[0]
...
对于每个配置文件,这是最好的方法,因为它不是干的,并且需要对数据库进行额外的查询

最好的方法是什么


编辑:最好在设置中定义AUTH\u PROFILE\u模块,以指向基础模型,如
AUTH\u PROFILE\u模块='profiles.baseprofile'
,并能够在每个具有从同一基础配置文件派生的不同配置文件类的用户上使用user.get\u PROFILE()

将其设置为OneToOneField而不是FK,然后执行
user.doctorprofile
等操作。如果出现问题,OneToOne将抛出Foo.DoesNotExist或Foo.multipleObject返回,因此,请准备捕获这些异常

将其设置为OneToOneField而不是FK,然后执行
user.doctor文件
等操作。OneToOne将抛出一个Foo.DoesNotExist或Foo.multipleObject返回,但如果出现问题,因此,请做好捕捉这些异常的准备

我可以问一下,为什么选择使用继承而不是组合或聚合作为划分不同类型用户的方式吗?为什么一个带有“is_a”标志的概要文件类不是正确的方法?然后您可以使用get_profile(),原因之一是,我提供的示例是一个简化的示例。在实际情况中,大约有10种不同的配置文件类型,具有许多常见和不常见的属性。为了让模型保持干爽,继承对我来说似乎更自然。即使我使用了组合,我相信我在尝试为用户获取配置文件时仍然会遇到同样的问题,不是吗?我可以问一下,为什么您选择使用继承而不是组合或聚合作为划分不同类型用户的方式吗?为什么一个带有“is_a”标志的概要文件类不是正确的方法?然后您可以使用get_profile(),原因之一是,我提供的示例是一个简化的示例。在实际情况中,大约有10种不同的配置文件类型,具有许多常见和不常见的属性。为了让模型保持干爽,继承对我来说似乎更自然。即使我使用了组合,我相信我在尝试为用户获取配置文件时仍然会遇到同样的问题,不是吗?谢谢,这会让事情变得更整洁。但这种方法仍然需要逐个查询每个配置文件的可能性,这意味着对数据库的额外点击,而且不是很枯燥,因为如果引入新的配置文件,另一次尝试。。。应将Exception块添加到获取配置文件的代码中。最好在BaseProfile类上使用get_profile()。我会更新我的问题。我没有说它是完美的。在Django中扩展用户模型要到1.3/1.4才能变得更好,我想。你可以添加一些代码(就像我所做的那样),在第一次需要的时候缓存概要文件,然后在模型再次保存时使其密钥无效。好吧,我来自未来,我要说的是,在Django 1.9之前,我们甚至没有类似的代码。谢谢,这将使事情变得更整洁。但这种方法仍然需要逐个查询每个配置文件的可能性,这意味着对数据库的额外点击,而且不是很枯燥,因为如果引入新的配置文件,另一次尝试。。。应将Exception块添加到获取配置文件的代码中。最好在BaseProfile类上使用get_profile()。我会更新我的问题。我没有说它是完美的。在Django中扩展用户模型要到1.3/1.4才能变得更好,我想。你可以添加一些代码(就像我所做的那样),在第一次需要的时候缓存概要文件,然后在模型再次保存时使其密钥无效。好吧,我来自未来,我要说的是,直到Django 1.9,我们都没有类似的代码。