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

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

问题描述

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

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?

推荐答案

(更新:对于 Django 1.2 和更新版本,可以跨反向 OneToOneField 关系(从而向下继承层次结构)跟踪 select_related 查询,有一种更好的技术可用,它不需要在父模型上添加 real_type 字段.它可作为 InheritanceManager>django-model-utils 项目.)

(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.)

通常的方法是在 Parent 模型上向 ContentType 添加一个 ForeignKey,该模型存储了正确的叶子"的内容类型.班级.如果没有这个,您可能必须对子表进行大量查询才能找到实例,具体取决于您的继承树的大小.以下是我在一个项目中的做法:

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 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

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

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天全站免登陆