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 オブジェクトTicketedConcert.objects.all()のみが表示されます。

私の意図は、 の特定のオブジェクトTicketedEvent.objects.all()が実際に TicketedConcert オブジェクトであるかどうかを検出することでした。すべての作業を で囲む必要はありませんtry:/except:

実際 オブジェクトであるオブジェクトのみが、モデルからの関連データを含むTicketedConcert属性 ( で指定.select_related())を持つと予想していました。サブクラスの属性の存在 (True/False として) に基づいて試行すると、次のエラーが発生しました。.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 に答える