用Django MTI找出孩子类型或指定类型为字段? [英] Figure out child type with Django MTI or specify type as field?
问题描述
我正在使用多表继承(MTI)在django中设置数据模型:
I'm setting up a data model in django using multiple-table inheritance (MTI) like this:
class Metric(models.Model):
account = models.ForeignKey(Account)
date = models.DateField()
value = models.FloatField()
calculation_in_progress = models.BooleanField()
type = models.CharField( max_length=20, choices= METRIC_TYPES ) # Appropriate?
def calculate(self):
# default calculation...
class WebMetric(Metric):
url = models.URLField()
def calculate(self):
# web-specific calculation...
class TextMetric(Metric):
text = models.TextField()
def calculate(self):
# text-specific calculation...
我的直觉是在基类中放置一个'type'字段,如这里所示,所以我可以知道Metric对象属于哪个子类。保持这个更新的时间一直是一个麻烦,但可能是一个麻烦。但是我需要这样做吗?有没有办法django自动处理?
My instinct is to put a 'type' field in the base class as shown here, so I can tell which sub-class any Metric object belongs to. It would be a bit of a hassle to keep this up to date all the time, but possible. But do I need to do this? Is there some way that django handles this automatically?
当我调用 Metric.objects.all()
每个对象返回的是 Metric
的实例,永远不会是子类。所以如果我调用 .calculate()
我从来没有得到子类的行为。
When I call Metric.objects.all()
every objects returned is an instance of Metric
never the subclasses. So if I call .calculate()
I never get the sub-class's behavior.
我可以写一个函数在基础测试,看看我是否可以将其转换为任何子类型,如:
I could write a function on the base class that tests to see if I can cast it to any of the sub-types like:
def determine_subtype(self):
try:
self.webmetric
return WebMetric
except WebMetric.DoesNotExist:
pass
# Repeat for every sub-class
但这似乎是一堆重复的代码。而且它也不能包含在SELECT过滤器中 - 只适用于python空间。
but this seems like a bunch of repetitious code. And it's also not something that can be included in a SELECT filter -- only works in python-space.
最好的方法是处理这个? b $ b
What's the best way to handle this?
推荐答案
虽然它可能会冒犯一些人的感觉,但解决这个问题的唯一实际方法是将一个字段或方法放在基类中说什么样的对象每个记录真的是。您描述的方法的问题是它需要为每种类型的子类,对于您要处理的每个对象单独的数据库查询。当使用大型查询时,这可能会变得非常慢。一个更好的方法是使用一个ForeignKey到django Content Type类。
While it might offend some people's sensibilities, the only practical way to solve this problem is to put either a field or a method in the base class which says what kind of object each record really is. The problem with the method you describe is that it requires a separate database query for every type of subclass, for each object you're dealing with. This could get extremely slow when working with large querysets. A better way is to use a ForeignKey to the django Content Type class.
@Carl Meyer在这里写了一个很好的解决方案:如何访问子类一个对象在django中,而不知道子类的名称?
@Carl Meyer wrote a good solution here: How do I access the child classes of an object in django without knowing the name of the child class?
单表继承可以帮助缓解这个问题,具体取决于它如何实现。但是现在Django不支持它: Django中的单表继承,因此它不是有用的建议。
Single Table Inheritance could help alleviate this issue, depending on how it gets implemented. But for now Django does not support it: Single Table Inheritance in Django so it's not a helpful suggestion.
这篇关于用Django MTI找出孩子类型或指定类型为字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!