django序列化器查询数据库的外键ID
我使用 django 序列化器序列化多个对象,但问题是每个序列化都会从数据库查询外键的 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)
I serialize several objects using django serializer but problem is each serialize queries the foerign key's id from db, instead of just taking it from object e.g.
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' ....}}]
Is there a way to change this behavior without modifying django code? I know a.company.id
will query company table (which should not happen in ideal world) but is there an option in serializer so that it does something like a.company_id
which will not query the db
>>> django.VERSION
(1, 3, 1, 'final', 0)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我最终修改了 django python 序列化器,以便它直接获取引用对象的 id,而不是从数据库获取它
我不确定它是否处理所有
ForeighKey
用例,但它适用于像这样的简单情况company = models.ForeignKey(Company)
还需要在settings.py中注册序列化器
我还提交了 bug ,现已在 django trunk 中修复。
查看变更集
I ended up modifying django python serializer so that it directly gets referenced object's id instead of getting it from db
I am not sure if it takes care of all
ForeighKey
usecase but it works for simple cases likecompany = models.ForeignKey(Company)
Also need to register serializer in settings.py
I also filed a bug for this, which is now fixed in django trunk.
see changset
您应该使用自然键。
本质上,这需要您在外键引用模型上定义一个名为
natural_key
的方法,该方法返回您希望拥有的字段,代替文档中的 pk:
然后设置参数 <序列化期间将 code>use_natural_keys 设置为
True
。再次,从文档中:
You should serialize using Natural Keys.
Essentially, this requires your to define a method called
natural_key
on the foreign key referenced model, that returns the fields you would rather have, in the place of the pkFrom the documentation:
and then set the parameter
use_natural_keys
toTrue
during serialization.Again, from the documentation:
我为避免额外查询所做的事情似乎也不是很有效,但它确实有效:将
select_lated(...)
添加到原始查询集中,以在初始查询中加载相关对象。例如:
What I am doing to avoid the extra queries seems not very efficient either, but it does the trick: add
select_related(...)
to your original queryset to load the related objects in the initial query.For example: