如何在django中访问对象的子类,而不知道子类的名称? [英] How do I access the child classes of an object in django without knowing the name of the child class?

查看:99
本文介绍了如何在django中访问对象的子类,而不知道子类的名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django中,当你有一个父类和多个从它继承的子类时,通常通过parentclass.childclass1_set或parentclass.childclass2_set来访问一个子代,但是如果我不知道特定子类的名字怎么办我想要吗?



有没有办法在父 - 子方向获取相关对象,而不知道子类名?

解决方案

更新:对于Django 1.2和更新版本,可以按照相反的OneToOneField关系(从而降低继承层次结构)一种更好的技术,不需要在父模型上添加 real_type 字段,它可以作为 InheritanceManager =nofollow noreferrer> djang o-model-utils 项目。)



通常的方式是在Parent模型上添加一个ForeignKey到ContentType,该模型存储内容类型适当的叶类。没有这个,您可能需要对子表进行相当多的查询以查找实例,具体取决于您的继承树的大小。这是我在一个项目中所做的工作:

 从django.contrib.contenttypes.models导入ContentType 
from django。 db import model

class InheritanceCastModel(models.Model):

提供一个real_typeFK到ContentType的抽象基类

对于继承模型的树,可以将
父实例下载到子类型


real_type = models.ForeignKey(ContentType ,editable = False)

def save(self,* args,** kwargs):
如果不是self._state.adding:
self.real_type = self._get_real_type( )
super(InheritanceCastModel,self).save(* args,** kwargs)

def _get_real_type(self):
返回ContentType.objects.get_for_model(type(self) )

def cast(self):
return self.real_type.get_object_for_this_type(pk = self.pk)

class Meta:
abstract = True

这是作为抽象基类实现的,使其可重用;您也可以将这些方法和FK直接放在特定继承层次结构中的父类上。



如果您无法修改该解决方案,则此解决方案将无法正常工作父母模型。在这种情况下,您将非常困难地手动检查所有子类。


In Django, when you have a parent class and multiple child classes that inherit from it you would normally access a child through parentclass.childclass1_set or parentclass.childclass2_set, but what if I don't know the name of the specific child class I want?

Is there a way to get the related objects in the parent->child direction without knowing the child class name?

解决方案

(Update: For Django 1.2 and newer, which can follow select_related queries across reverse OneToOneField relations (and thus down inheritance hierarchies), there's a better technique available which doesn't require the added real_type field on the parent model. It's available as InheritanceManager in the django-model-utils project.)

The usual way to do this is to add a ForeignKey to ContentType on the Parent model which stores the content type of the proper "leaf" class. Without this, you may have to do quite a number of queries on child tables to find the instance, depending how large your inheritance tree is. Here's how I did it in one project:

from django.contrib.contenttypes.models import ContentType
from django.db import models

class InheritanceCastModel(models.Model):
    """
    An abstract base class that provides a ``real_type`` FK to ContentType.

    For use in trees of inherited models, to be able to downcast
    parent instances to their child types.

    """
    real_type = models.ForeignKey(ContentType, editable=False)

    def save(self, *args, **kwargs):
        if not self._state.adding:
            self.real_type = self._get_real_type()
        super(InheritanceCastModel, self).save(*args, **kwargs)

    def _get_real_type(self):
        return ContentType.objects.get_for_model(type(self))

    def cast(self):
        return self.real_type.get_object_for_this_type(pk=self.pk)

    class Meta:
        abstract = True

This is implemented as an abstract base class to make it reusable; you could also put these methods and the FK directly onto the parent class in your particular inheritance hierarchy.

This solution won't work if you aren't able to modify the parent model. In that case you're pretty much stuck checking all the subclasses manually.

这篇关于如何在django中访问对象的子类,而不知道子类的名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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