0

我的问题:在 Model 类的save()clean()和 one-off 方法中,对子模型的父级进行了引用。这些引用在子代模型中失败,因为需要引用父代的父代。检查[object].[child-class name as attribute]失败,因为所有对象都具有此属性,但尝试在子类表中没有相关对象的对象上访问它会导致异常。

给定以下模型:

...
from django_extensions.db.fields import UUIDField

class Event(models.Model):
    uuid = UUIDField()
    ...

class TicketedEvent(Event):
    ...

    def save():
        # Do work with the parent's data
        ... self.event.uuid ...
        # TicketedConcert objects use this save() as well
        # but need to refer to self.ticketedevent.event.uuid

class TicketedConcert(TicketedEvent):
    ...

在查看结果时,TicketedEvent.objects.all()我看到了所有 TicketedEvent 和 TicketedConcert 对象,而查看结果中TicketedConcert.objects.all()只显示了 TicketedConcert 对象。

我的意图是检测给定对象TicketedEvent.objects.all()是否实际上是 TicketedConcert 对象,而不需要将我所有的工作都包含在try:/except:.

我希望只有实际上 对象的对象才会具有包含模型相关数据TicketedConcert的属性(由 给出.select_related())。当试图基于子类属性的存在(如真/假)时,这给了我以下错误:.ticketedconcertTicketedConcert.exclude()

>>> TicketedEvent.objects.select_related().exclude(ticketedconcert=True)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/Bryson/.virtualenvs/spyon/lib/python2.7/site-packages/django/db/models/query.py", line 557, in exclude
    return self._filter_or_exclude(True, *args, **kwargs)
  File "/Users/Bryson/.virtualenvs/spyon/lib/python2.7/site-packages/django/db/models/query.py", line 566, in _filter_or_exclude
    clone.query.add_q(~Q(*args, **kwargs))
  File "/Users/Bryson/.virtualenvs/spyon/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1191, in add_q
    self.add_q(child, used_aliases, force_having=force_having)
  File "/Users/Bryson/.virtualenvs/spyon/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1194, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/Users/Bryson/.virtualenvs/spyon/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1072, in add_filter
    can_reuse)
  File "/Users/Bryson/.virtualenvs/spyon/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1521, in split_exclude
    if active_positions[-1] > 1:
IndexError: list index out of range
>>> 

此外,我尝试.exclude()基于存在/空值如下:

>>> TicketedEvent.objects.select_related().exclude(ticketedconcert__isnull=True)
[<TicketedEvent: Event Name>, <TicketedEvent: Event Name>]

实际上,两个返回的事件都是一个TicketedConcert. 检查子类是否存在作为属性的 null 仅返回实际具有子类对象的对象。显然,父模型返回的每个对象都将子类作为属性,但在非子类对象上访问它会失败。我对此的预期结果是,只有实际具有关联子类对象的对象才会具有该属性。

这是我的问题。当被父类访问时,我如何才能真正判断一个对象是否实际上在该属性中具有数据(因此实际上是一个子类)?

我最初的尝试如下:

if hasattr(self, ticketedconcert):
    # do a different set of work on this data, it's a concert
else:
    # do normal, non-concert work upon this data

这继续给我错误,因为每个对象都具有该属性,无论其使用能力如何。

4

1 回答 1

1
Event.objects.exclude(
    id__in=TicketedConcert.objects.values_list('id', flat=True)
)

“我的目​​的是防止 TicketedConcert 子类对象包含在父类的结果中。”

TicketedEvent.objects.exclude(
    id__in=TicketedConcert.objects.values_list('id', flat=True)
)

我不确定这是否是使用实例的最佳解决方案。例如:

if tevent.id in TicketedConcert.objects.values_list('id', flat=True):
    # the event is a concert
else:
    # the event is not a TicketedConcert

但是,它会起作用并且不会太糟糕(也许)。

于 2012-05-23T05:18:38.513 回答