prefetch_related
でアプリを高速化しようとしています。 GenericForeignKey
の関係に従うことができ、それは__
で深くなる可能性がありますが、残念ながら関連モデルにこのようなフィールドがないと失敗します。ここで同じDB列に複数のフィールドがあります
がモデル構造
class ModelA(models.Model):
event_object = models.ForeignKey(SomeModelA)
class ModelB(models.Model):
event = models.ForeignKey(SomeModelB)
class ModelC(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
のいくつかの例であるのでModelC
インスタンスがModelA
またはModelB
のいずれかを指すことができます。そして、私はAとBの両方のモデルをプリフェッチするためにこのようなクエリセットを使用することができます。ModelC.objects.all().prefetch_related('content_object')
残念ながら、私はまた、イベントオブジェクト(SomeModelA
またはSomeModelB
)を選択する必要が
を私は
ModelC.objects.all().prefetch_related('content_object', 'content_object__event_object')
を実行しようとするとそれがうまくいくかどうかはインスタンスはModelA
を指しますが、ModelB
にはevent_object
フィールドがなく、代わりにevent
があるため、失敗する可能性があります。
このモデルはコードの多くの場所で使用されているため、フィールドの名前を変更することはお勧めできません。フィールド/列のエイリアスを作成する方法があるのだろうかと思います。
私はこのようにやろうとした:DBテーブルの同じ列を指す2つのフィールドを作るために
class ModelB(models.Model):
event = models.ForeignKey(SomeModelB)
event_object = models.ForeignKey(SomeModelB, db_column='event_id', related_name='+')
。しかし、これは、save
メソッドを壊すので動作しません。 DjangoはUPDATE
SQLクエリを作成し、1列が2回配置され、DatabaseErrorを取得します。
このようなエイリアスを作成する方法はありますか?または、例外をスローしないようにprefetch_related
を作成する別の解決方法がありますか?
更新:save
方法では、このフィールドを除外するために使用することができますupdate_fields
パラメータがあります。しかし1.5に導入され、1.4を使用しています。だから私は答えを探し続ける。
更新#2:@ shx2がトレースバックを提供するように頼んだ。トレースバックは2つあります。 第一 - 属性は、最初のオブジェクトの上に欠落している場合:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 72, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 97, in __iter__
len(self)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 89, in __len__
self._prefetch_related_objects()
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 570, in _prefetch_related_objects
prefetch_related_objects(self._result_cache, self._prefetch_related_lookups)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 1664, in prefetch_related_objects
(attr, first_obj.__class__.__name__, lookup))
AttributeError: Cannot find 'event_object' on ModelB object, 'content_object__event_object' is an invalid parameter to prefetch_related()
そしてprefetch_relatedパラメータが第一の目的のために有効であるならば、私は2番目のトレースバックを得る:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 72, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 97, in __iter__
len(self)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 89, in __len__
self._prefetch_related_objects()
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 570, in _prefetch_related_objects
prefetch_related_objects(self._result_cache, self._prefetch_related_lookups)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 1680, in prefetch_related_objects
obj_list, additional_prl = prefetch_one_level(obj_list, prefetcher, attr)
File "/home/igor/workspace/projectname/eggs/Django-1.4.2-py2.7.egg/django/db/models/query.py", line 1803, in prefetch_one_level
qs = getattr(obj, attname).all()
AttributeError: 'ModelB' object has no attribute 'event_object'
'prefetch_related'エラーのトレースバックを追加できますか? – shx2
なぜModelCクエリーセットが必要ですか? 2つの異なるクエリを作成し、それらを別々に扱うことはできませんか?私は私の質問が少し素朴であることを知っているが、ときどき問題はちょうど私たちがこの困難に直面している方法です。 – marianobianchi
@marianobianchiいいえ、私たちはdjangoの管理者の一部を最適化しようとします。上記のモデルも簡素化されており、実際のプロジェクトではより深い関係がある – Igor