如何找到“具体类”的django模型baseclass [英] How do I find the "concrete class" of a django model baseclass

查看:99
本文介绍了如何找到“具体类”的django模型baseclass的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



一些代码来描述问题:

>

  class Base(models.model):
def basemethod(self):
...

class Child_1(Base):
pass

class Child_2(Base):
pass

如果我创建两个Child类的各种对象,并创建一个包含它们的查询集:

  Child_1()。save()
Child_2()。save()
(o1,o2)= Base.objects.all()

我想确定对象在basemethod中是否类型为Child_1或Child_2,我可以通过o1.child_1和o2获取子对象。 child_2但是重新获得有关基础类中的子类的知识。



我已经提出了以下代码:

  def concrete_instance(self):
instance = None
for self._meta.get中的子类_all_related_objects():
acc_name = subclass.get_accessor_name()
try:
instance = self .__ getattribute __(acc_name)
返回实例
除了异常,e:
pass

但感觉很脆弱,我不知道如果我继承的话会发生什么更多级别。

解决方案

Django使用父模型表和子模型表之间的OneToOneField实现模型继承。当您执行 Base.object.all()时,Django正在查询基表,因此无法知道子表是什么。因此,不幸的是,不可能直接进入子模型实例而不需要额外的查询。



这个片段显示了一种向基本模型添加ContentType字段的常见方法:

 code> from django.contrib.contenttypes.models import ContentType 

class Base(models.Model):
content_type = models.ForeignKey(ContentType,editable = False,null = True )

def save(self):
if(not self.content_type):
self.content_type = ContentType.objects.get_for_model(self .__ class__)
self .save_base()

def as_leaf_class(s​​elf):
content_type = self.content_type
model = content_type.model_class()
if(model == Base)
return self
return model.objects.get(id = self.id)

如果可以,你可以说 Base.content_type.model_class()来确定类型。



这里是将一个自定义管理器添加到组合中的另一个代码段。



正如你所看到的,这些解决方案有可能非常昂贵。如果您有大量的实例,则使用as_leaf_class()方法将需要对每个项目进行一次查询。



相反,如果您有一组已知的子模型,只需单独查询每个模型,并将实例聚合到一个列表中。


I'm trying to find the actual class of a django-model object, when using model-inheritance.

Some code to describe the problem:

class Base(models.model):
    def basemethod(self):
        ...

class Child_1(Base):
    pass

class Child_2(Base):
    pass

If I create various objects of the two Child classes and the create a queryset containing them all:

Child_1().save()
Child_2().save()
(o1, o2) = Base.objects.all()

I want to determine if the object is of type Child_1 or Child_2 in basemethod, I can get to the child object via o1.child_1 and o2.child_2 but that reconquers knowledge about the childclasses in the baseclass.

I have come up with the following code:

def concrete_instance(self):
    instance = None
    for subclass in self._meta.get_all_related_objects():
        acc_name = subclass.get_accessor_name()
        try:
            instance = self.__getattribute__(acc_name)
            return instance
        except Exception, e:
            pass

But it feels brittle and I'm not sure of what happens when if I inherit in more levels.

解决方案

Django implements model inheritance with a OneToOneField between the parent model's table and the child model's table. When you do Base.object.all(), Django is querying just the Base table, and so has no way of knowing what the child table is. Therefore, unfortunately, it's not possible to go directly to the child model instance without additional queries.

This snippet shows a common method of adding a ContentType field to the base model:

from django.contrib.contenttypes.models import ContentType

class Base(models.Model):
    content_type = models.ForeignKey(ContentType,editable=False,null=True)

    def save(self):
        if(not self.content_type):
            self.content_type = ContentType.objects.get_for_model(self.__class__)
        self.save_base()

    def as_leaf_class(self):
        content_type = self.content_type
        model = content_type.model_class()
        if(model == Base):
            return self
        return model.objects.get(id=self.id)

You can then say if Base.content_type.model_class() to determine the type.

Here is another snippet that adds a custom manager into the mix.

As you can see, both of these solutions have the potential to be extremely expensive. If you have a large number of instances, using the as_leaf_class() method will require one query on each item.

Instead, if you have a known set of child models, simply query each model separately and aggregate the instances into one list.

这篇关于如何找到“具体类”的django模型baseclass的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆