在 Django CBV 上序列化上下文?
Serializing context on Django CBV?
我在序列化第 3 方包 (django-organizations) 时遇到问题,因为我想在 JSON 中接收上下文。
class本身是这样的:
class OrganizationUserMixin(OrganizationMixin, JSONResponseMixin):
"""Mixin used like a SingleObjectMixin to fetch an organization user"""
user_model = OrganizationUser
org_user_context_name = 'organization_user'
def get_user_model(self):
return self.user_model
def get_context_data(self, **kwargs):
kwargs = super(OrganizationUserMixin, self).get_context_data(**kwargs)
kwargs.update({self.org_user_context_name: self.object,
self.org_context_name: self.object.organization})
return kwargs
def get_object(self):
""" Returns the OrganizationUser object based on the primary keys for both
the organization and the organization user.
"""
if hasattr(self, 'organization_user'):
return self.organization_user
organization_pk = self.kwargs.get('organization_pk', None)
user_pk = self.kwargs.get('user_pk', None)
self.organization_user = get_object_or_404(
self.get_user_model().objects.select_related(),
user__pk=user_pk, organization__pk=organization_pk)
return self.organization_user
我正在尝试将此自定义 JSONResponseMixin 传递给我的 OrganizationUserMixin
class:
class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
print(context)
return context
然后覆盖 OrganizationUserMixin
中的 render_to_response
如下:
def render_to_response(self, context, **response_kwargs):
return self.render_to_json_response(context, **response_kwargs)
如果我打印 context
看起来像这样
# {
# 'object': <OrganizationUser: Erik (MyOrgName)>,
# 'organizationuser': <OrganizationUser: Erik (MyOrgName)>,
# 'organization': <Organization: MyOrgName>,
# 'view': <organizations.views.OrganizationUserDetail object at 0x1091a3ac0>,
# 'organization_user': <OrganizationUser: Erik (MyOrgName)>
# }
我得到的错误信息是TypeError: Object of type OrganizationUser is not JSON serializable
如何在我的 JSONResponseMixin 中序列化 context
?
这里有两个选择,使用 Django rest framework (DRF) 或实现为模型执行序列化的函数。
选项 1
DRF 是一个更可持续的解决方案,因为它会抽象大部分 de/serialization 工作,并为您提供许多其他有用的功能,例如路由器、ViewSet 和其他。
示例代码
# serializers.py
from rest_framework import serializers
class OrganizationUserSerializer(serializers.ModelSerializer):
class Meta:
model = OrganizationUser
fields = '__all__'
# views.py
from rest_framework import generics
class OrganizationUser(generics.RetrieveModelMixin):
queryset = OrganizationUser.objects.all()
serializer_class = OrganizationUserSerializer
选项 2
也就是说,如果 JsonResponseMixin
足以满足您的大部分需求,并且您的应用程序不主要依赖于 API,您只需为您的模型并在您的 JsonResponseMixin.get_data()
中调用它们
示例代码:
# Models.py
class OrganizationUser(models.Model):
...
def to_json(self):
# assuming you have a field name and organization
return {"name": self.name, "organization": self.organization.to_json()}
# mixins.py
class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
data = {}
for key, val in context:
if hasattr(val, "to_json"):
data[key] = val.to_json()
else:
data[key] = val
return data
我在序列化第 3 方包 (django-organizations) 时遇到问题,因为我想在 JSON 中接收上下文。
class本身是这样的:
class OrganizationUserMixin(OrganizationMixin, JSONResponseMixin):
"""Mixin used like a SingleObjectMixin to fetch an organization user"""
user_model = OrganizationUser
org_user_context_name = 'organization_user'
def get_user_model(self):
return self.user_model
def get_context_data(self, **kwargs):
kwargs = super(OrganizationUserMixin, self).get_context_data(**kwargs)
kwargs.update({self.org_user_context_name: self.object,
self.org_context_name: self.object.organization})
return kwargs
def get_object(self):
""" Returns the OrganizationUser object based on the primary keys for both
the organization and the organization user.
"""
if hasattr(self, 'organization_user'):
return self.organization_user
organization_pk = self.kwargs.get('organization_pk', None)
user_pk = self.kwargs.get('user_pk', None)
self.organization_user = get_object_or_404(
self.get_user_model().objects.select_related(),
user__pk=user_pk, organization__pk=organization_pk)
return self.organization_user
我正在尝试将此自定义 JSONResponseMixin 传递给我的 OrganizationUserMixin
class:
class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
print(context)
return context
然后覆盖 OrganizationUserMixin
中的 render_to_response
如下:
def render_to_response(self, context, **response_kwargs):
return self.render_to_json_response(context, **response_kwargs)
如果我打印 context
看起来像这样
# {
# 'object': <OrganizationUser: Erik (MyOrgName)>,
# 'organizationuser': <OrganizationUser: Erik (MyOrgName)>,
# 'organization': <Organization: MyOrgName>,
# 'view': <organizations.views.OrganizationUserDetail object at 0x1091a3ac0>,
# 'organization_user': <OrganizationUser: Erik (MyOrgName)>
# }
我得到的错误信息是TypeError: Object of type OrganizationUser is not JSON serializable
如何在我的 JSONResponseMixin 中序列化 context
?
这里有两个选择,使用 Django rest framework (DRF) 或实现为模型执行序列化的函数。
选项 1
DRF 是一个更可持续的解决方案,因为它会抽象大部分 de/serialization 工作,并为您提供许多其他有用的功能,例如路由器、ViewSet 和其他。
示例代码
# serializers.py
from rest_framework import serializers
class OrganizationUserSerializer(serializers.ModelSerializer):
class Meta:
model = OrganizationUser
fields = '__all__'
# views.py
from rest_framework import generics
class OrganizationUser(generics.RetrieveModelMixin):
queryset = OrganizationUser.objects.all()
serializer_class = OrganizationUserSerializer
选项 2
也就是说,如果 JsonResponseMixin
足以满足您的大部分需求,并且您的应用程序不主要依赖于 API,您只需为您的模型并在您的 JsonResponseMixin.get_data()
示例代码:
# Models.py
class OrganizationUser(models.Model):
...
def to_json(self):
# assuming you have a field name and organization
return {"name": self.name, "organization": self.organization.to_json()}
# mixins.py
class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
data = {}
for key, val in context:
if hasattr(val, "to_json"):
data[key] = val.to_json()
else:
data[key] = val
return data