2

私はdjangoシリアライザーを使用していくつかのオブジェクトをシリアル化しますが、問題は、オブジェクトから取得するだけでなく、各シリアル化がdbから外部キーのIDをクエリすることです。

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 コードを変更せずにこの動作を変更する方法はありますか? 会社のテーブルにクエリを実行することはわかっていますが(理想的な世界では発生しないはずです)、シリアライザーにオプションがあり、データベースにクエリを実行しないa.company.idようなことを行いますa.company_id

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

3 に答える 3

1

I ended up modifying django python serializer so that it directly gets referenced object's id instead of getting it from db

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)

I am not sure if it takes care of all ForeighKey usecase but it works for simple cases like company = models.ForeignKey(Company)

Also need to register serializer in settings.py

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

I also filed a bug for this, which is now fixed in django trunk. see changset

于 2012-01-27T17:40:49.160 に答える
0

Natural Keysを使用してシリアル化する必要があります。

基本的に、これnatural_keyには外部キー参照モデルで呼び出されるメソッドを定義する必要があります。これは、pk の代わりに、必要なフィールドを返します。

ドキュメントから:

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'),)

次に、シリアル化中にパラメーターuse_natural_keysをに設定しますTrue

繰り返しますが、ドキュメントから:

>>> serializers.serialize('json', [book1, book2], indent=2, use_natural_keys=True)
于 2012-01-27T16:09:44.683 に答える