简体   繁体   English

When using Generics types, how can I call an Attribute of an inherited class on the Base class instance with Python / Django?

[英]When using Generics types, how can I call an Attribute of an inherited class on the Base class instance with Python / Django?

Let's say I have a base Generic class called person to group all other persons that extend it:假设我有一个名为 person 的基本通用 class 来对扩展它的所有其他人进行分组:

class Person(models.Model):
    name = models.CharField(...)

And the class Worker, that extends the Person:以及扩展 Person 的 class Worker:

class Worker(Person):
    card_id = models.CharField(...)

When I access all Person objects I also see the Workers, but lets say that from there I want to do this:当我访问所有 Person 对象时,我也看到了 Workers,但可以说从那里我想这样做:

worker = Worker(name='Example', card_id='1234')

person = Person.objects.all().first()

Let's say that for some reason I want to use the Person class and call an Attribute o Worker:假设由于某种原因我想使用 Person class 并调用 Attribute o Worker:

[in] person.card_id
# Somehow expecting this result:
[out] '1234

Is it possible, is it viable and how do I do it?是否可能,是否可行,我该怎么做?

I'm afraid this is not possible, even when you can guarantee that the Person object you retrieved (ie. Person.objects.all().first() ) is also a Worker .恐怕这是不可能的,即使您可以保证您检索到的Person object (即Person.objects.all().first() )也是Worker

There three styles of inheritance possible in Django: Abstract Base classes , Proxy Models , and Multi-Table Inheritance Django 中可能有 inheritance 的三个 styles: 抽象基类代理模型多表 ZE58BB489C13E702

In this case, you are using Multi-Table Inheritance .在这种情况下,您使用的是多表 Inheritance As the name suggest, each model will receive its own table in the database and can therefore also be queried.顾名思义,每个 model 都会在数据库中收到自己的表,因此也可以进行查询。

When querying for Person objects, what you will end up with are Person instances, not Worker instances or any other child class instance.在查询Person对象时,您最终会得到Person实例,而不是Worker实例或任何其他子 class 实例。 Since the card_id field is not defined in the Person model, but rather in one of its child models, you will get an error when trying to retrieve the card_id value of Person instance, even though the instance is also a Worker .由于card_id字段未在Person model 中定义,而是在其子模型之一中定义,因此在尝试检索Person实例的card_id值时会出错,即使该实例也是Worker

However, if you know that your Person instance is also a Worker , you can retrieve it via:但是,如果您知道您的Person实例也是一个Worker ,您可以通过以下方式检索它:

person = Person.objects.all().first()
worker = person.worker

This works because the inheritance relationship creates a OneToOneField between the child and each of its parents.这是因为 inheritance 关系在孩子和它的每个父母之间创建了一个OneToOneField However, note that this will give an error in case the person instance is not actually a Worker .但是,请注意,如果person实例实际上不是Worker ,这将给出错误。

One library that might help is the InheritanceManager from django-model-utils .一个可能有帮助的库是django-model-utilsInheritanceManager

By attaching the InheritanceManager to your base class model such as:通过将 InheritanceManager 附加到您的基础 class model 例如:

from model_utils.managers import InheritanceManager

class Person(models.Model):
    objects = InheritanceManager()
    # ...

You can then use the .select_subclasses filter to filter a queryset of the Parent model to only include the objects of a particular child class.然后,您可以使用.select_subclasses过滤器过滤父 model 的查询集,以仅包含特定子 class 的对象。 For example to only select the persons that are also workers, you can do the following query:例如,对于同时也是工人的人,您可以执行以下查询:

persons_worker = Person.objects.select_subclasses(Worker)

and you should never run into troubles when trying to do retrieve the card_id for any of the instances in persons_worker .并且在尝试为persons_worker中的任何实例检索card_id时,您永远不应该遇到麻烦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 继承的类无法使用exec调用python中的基本方法 - inherited class can not call base method in python using exec 我可以使用实例属性调用 class 的实例吗? - Can I call an instance of a class using its instance attribute? 如何在unittest Python中创建继承的类的实例,以便我可以在simpleXMLRPCServer中注册该类的实例 - How to create an instance of an inherited class in unittest Python so that I can register the instance of that class in simpleXMLRPCServer Python-自动更新继承的类别中的基础类别属性(别名) - Python - Automatically update base class attribute (alias) in inherited class 如何在Python中调用特定的基类方法? - How can I call a particular base class method in Python? 当继承 class 需要继承 ZA7F5F35426B9237811FC9231DZ 中的 class 时,如何从基础 class 继承? - How to inherit from a base class, when the inheriting class requires the inherited class in Python? 如何将_not_继承的属性添加到python * class *? - How to add attribute to python *class* that is _not_ inherited? 如何调用超出类的方法,并在python django中将类实例传递给它 - how to call a method that is out of the class and pass the class instance to it in python django Python继承的基类变量 - Python inherited base class variables Python - 如何使用基础 class 中的方法获取派生 class 的属性 - Python - How to get an attribute of a derived class using a method in the base class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM