像SELECT *, 'hello' AS world FROM myApp_myModel
这样的查询我希望将其序列化为json。
看起来不是什么大问题,并且在SO上有很多类似的问题,但似乎都没有给出直接答案。
到目前为止,我已尝试过:
data = myModel.objects.raw(query)
# gives: ModelState is not serializable
json.dumps([dict(r.__dict__) for r in data])
# doesn't serialize 'world' column, only model fields:
serializers.serialize('json', data)
#dear God:
for r in data:
for k in dict(r.__dict__):
print(getattr(r,k))
答案 0 :(得分:1)
您可以为任务创建DRF搜索器:
http://www.django-rest-framework.org/api-guide/serializers/
即
class MyModelSerializer(serializers.ModelSerializer):
world = serializers.ReadOnlyField()
class Meta:
model = MyModel
fields = (world, ...)
您也可以使用序列化程序继承等 - 请参阅文档。
答案 1 :(得分:1)
内置django core serializers还没有准备好包含额外的字段(来自原始的,也没有来自注释表达式)它只需要来自_meta.local_fields
的模型字段。
您可以在django django/core/serializers/base.py源代码中看到它:
concrete_model = obj._meta.concrete_model #obj is an object model
...
for field in concrete_model._meta.local_fields:
if field.serialize or field is pk_parent:
if field.remote_field is None:
if (self.selected_fields is None
or field.attname in self.selected_fields):
self.handle_field(obj, field)
else:
if (self.selected_fields is None
or field.attname[:-3] in self.selected_fields):
self.handle_fk_field(obj, field)
要解决您的问题,您可以使用非内置功能。您可以在项目中包含REST包。例如django rest framework可以处理额外的字段:
from django.db.models import F
from aula.apps.alumnes.models import MyModel
from rest_framework.renderers import JSONRenderer
data=MyModel.objects.annotate(dummy = F('some_field') )
class MyModelSerializer(serializers.ModelSerializer):
dummy = serializers.CharField()
class Meta:
model = MyModel
fields = ('some_other_field','dummy')
read_only_fields = (
'dummy',
)
m=MyModelSerializer(data, many=True)
JSONRenderer().render(m.data)
答案 2 :(得分:0)
有一种干净的方法可以使用Django Rest Framework做到这一点
首先您知道吗,您还可以执行包含未在模型上进行原始查询的字段的查询
例如(REF)
>>> people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person')
>>> for p in people:
... print("%s is %s." % (p.first_name, p.age))
John is 37.
Jane is 42.
这意味着您可以使用标准的串行器。您只需要告诉序列化程序如何处理模型上最初不存在的字段,请考虑以下内容。需要将3个表联接到一个用户。用户,他们所属的公司以及公司成员身份。如果您的表有成千上万的用户,并且您执行了标准的serializer方法字段,则将导致成千上万的查询,每次都获得相关公司的成员资格。所以这是我使用的解决方案
# api.py
class UserSAMAExportListApiView(ListAPIView):
serializer_class = UserExportSerializer
model = User
def get_queryset(self):
q = User.objects.raw(
"""
SELECT
[users_user].[id],
[users_user].[email],
[companies_company].[title] AS company__title,
[companies_company].[registration_number] AS company__registration_number,
[memberships_membership].number AS company__membership__number
FROM [users_user]
LEFT OUTER JOIN [dbo].[companies_company]
ON ([users_user].[company_id] = [companies_company].[id])
LEFT OUTER JOIN [memberships_membership]
ON ([companies_company].[id] = [memberships_membership].[company_id])
WHERE ([memberships_membership].[expiry_date] >= %s)
"""
, [date.today(),]
)
return q
然后只告诉您的标准序列化程序,您定义了一些新字段
# serializers.py
class UserExportSerializer(ModelSerializer):
class Meta:
model = User
fields = (
'id',
'email',
'company__title',
'company__registration_number',
'company__membership__number',
)
def build_unknown_field(self, field_name, model_class):
"""
Return a two tuple of (cls, kwargs) to build a serializer field with. For fields that werent originally on
The model
"""
return fields.CharField, {'read_only': True}
就是这样,DRF将以标准方式处理其余部分并为您进行适当的序列化
请注意,您必须覆盖build_unknown
_ fields方法。这只是说将所有非标准模型字段转换为文本,如果需要,您可以在此处检查字段名称并转换为其他格式。