当我有一个给定的django模型类时:
class BaseClass(models.Model):
some_field = models.CharField(max_length = 80)
...
及其中的一些子类,例如
class SomeClass(BaseClass):
other_field = models.CharField(max_length = 80)
然后我知道我可以通过调用
来获取派生对象base = BaseClass.objects.get(pk=3)
my_obj= base.someclass
现在问题出现了我有多个子类,而我所拥有的只是基类的一个实例。如何在不事先知道类的情况下才能访问子类对象?
这个想法是加载一个相应的视图,并让它做的事情。我的项目功能只对这些模型有一组有限的默认操作,如查看,编辑,删除等。我不想要的是通过URL公开给定对象的类型,因此“正常方式”不可用
答案 0 :(得分:3)
没有内置方式。
也许最好的办法是在基类上定义一个derived_type
字段,该字段在保存派生类时自动设置。然后,您可以在基础上使用get_derived
方法检查derived_type
的值并返回实际的派生对象。
答案 1 :(得分:2)
如何在不事先知道类的情况下才能访问子类对象?
为什么这会有用?如果你不知道你想要什么课程,你也不会知道要调用哪些方法或者可以检查哪些属性。
这个想法是加载一个相应的视图,并让它做的事情。我的项目功能只对这些模型有一组有限的默认操作,如查看,编辑,删除等。我不想要的是通过URL公开给定对象的类型,因此“正常方式”不可用
如果您提前知道模型子类集,或者愿意使用中央视图列表注册它们,您可以执行以下操作:
VIEWS = [('subclass_a', a_views), ('subclass_b', b_views)]
def edit(request):
base = (get base somehow)
for attrname, views in VIEWS:
if getattr(base, attrname) is not None:
return views['edit']
根据您拥有的不同类型的视图,您可以将搜索抽象为单独的函数,因此结束视图类似于:
def edit(request):
return generic_base_view(request, 'edit')
答案 2 :(得分:2)
对于那些比这个问题发布时间更晚的人来看这个答案并且已经接受了答案,在较新版本的django中,这可能更直接,请参阅: django documentation about multi table inheritance
看看地方和餐馆的例子。基础对象是一个地方,子类是一个餐馆。您可以通过place.restaurant获取子类,如果该地方不是餐馆,您可以获得例外。 我补充说,因为接受的答案可能有点过时,导致我走错了路。
答案 3 :(得分:0)
如果您使用django-model-utils中的InheritanceManager,那么您可以在查询时选择子类,而无需提前知道它们是什么。
https://django-model-utils.readthedocs.org/en/latest/managers.html#inheritancemanager