2012-01-27 4 views
2

私はdjangoシリアライザを使用していくつかのオブジェクトをシリアル化しますが、問題は各シリアル化はオブジェクトから取り出すのではなく、djangoシリアライザはforign key idのためにdbをクエリします

class QBAccount(CompanyModel): 
    company = models.ForeignKey(Company) 

>>> from deretoapp.models import QBAccount 
>>> import logging 
>>> l = logging.getLogger('django.db.backends') 
>>> l.setLevel(logging.DEBUG) 
>>> l.addHandler(logging.StreamHandler()) 
>>> a = QBAccount.allobjects.all()[0] 
>>> from django.core import serializers 
>>> serializers.serialize('python', [a]) 
(0.000) SELECT `deretoapp_company`.`id`, ... FROM `deretoapp_company` WHERE `deretoapp_company`.`id` = 45995613-adeb-488f-9556-d69e856abe5f ; args=(u'45995613-adeb-488f-9556-d69e856abe5f',) 
[{'pk': u'3de881eb-8409-4089-8de8-6e24f7281f37', 'model': u'deretoapp.qbaccount', 'fields': {... 'company': u'45995613-adeb-488f-9556-d69e856abe5f' ....}}] 

djangoコードを変更せずにこの動作を変更する方法はありますか?私はそれはあなたがNatural Keysを使用してシリアル化する必要があるデシベル

>>> django.VERSION 
(1, 3, 1, 'final', 0) 

答えて

0

を照会しませんa.company_idのような何かをするようにa.company.idは、会社のテーブルを照会します(理想的な世界では起こらないはずである)が、シリアライザでのオプションがあります知っています。

class Person(models.Model): 
    objects = PersonManager() 

    first_name = models.CharField(max_length=100) 
    last_name = models.CharField(max_length=100) 

    birthdate = models.DateField() 

    def natural_key(self): 
     return (self.first_name, self.last_name) 

    class Meta: 
     unique_together = (('first_name', 'last_name'),) 

基本的に、これは、文書からPK

の代わりに、あなたはむしろだろうフィールドを返す外部キー参照モデルにnatural_keyと呼ばれるメソッドを定義するためにあなたを必要とし

を入力し、シリアル化中にパラメータuse_natural_keysTrueに設定します。

は再び、ドキュメントから:それは代わりに、直接

from django.core.serializers.python import Serializer as PythonSerializer 
from django.core.serializers.python import Deserializer 

class Serializer(PythonSerializer): 
    internal_use_only = False 

    def handle_fk_field(self, obj, field): 
     if not self.use_natural_keys: 
      # directly get the id 
      self._current[field.name] = getattr(obj, field.attname) 
      return 

     return super(Serializer, self).handle_fk_field(obj, field) 

デシベルからそれを得るための参照されたオブジェクトのIDを取得するよう

>>> serializers.serialize('json', [book1, book2], indent=2, use_natural_keys=True) 
+0

これは、DBクエリを避けられないだろうと私は 'のIDすなわちpk'ない自然キーたいです –

1

私がもしわからないDjangoのパイソン・シリアライザを修正することになりましたそれはすべてのForeighKey usecaseの世話をしますが、簡単な場合のように動作しますcompany = models.ForeignKey(Company)

また、 settings.py

SERIALIZATION_MODULES = { 'python' : 'myapp.serializers.python' } 

でlizerは私も今Djangoのトランクに固定され、このためbugを提出しました。私は余分なクエリを避けるために、何をやっている see changset

0

は、いずれかの非常に効率的ではないようだが、それはトリックを行います。最初のクエリに関連するオブジェクトをロードするために元のクエリセットにselect_related(...)を追加します。例えば

a = QBAccount.allobjects.select_related('company').all()[0] 
関連する問題