私の問題: 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 オブジェクトTicketedConcert.objects.all()
のみが表示されます。
私の意図は、 の特定のオブジェクトTicketedEvent.objects.all()
が実際に TicketedConcert オブジェクトであるかどうかを検出することでした。すべての作業を で囲む必要はありませんtry:/except:
。
実際に オブジェクトであるオブジェクトのみが、モデルからの関連データを含むTicketedConcert
属性 ( で指定.select_related()
)を持つと予想していました。サブクラスの属性の存在 (True/False として) に基づいて試行すると、次のエラーが発生しました。.ticketedconcert
TicketedConcert
.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
すべてのオブジェクトは、その使用能力に関係なくその属性を持っているため、これは引き続きエラーを発生させました。