Django Rest 框架:将查询集传递给 Response()

Posted

技术标签:

【中文标题】Django Rest 框架:将查询集传递给 Response()【英文标题】:Django Rest framework : passing queryset to Response() 【发布时间】:2016-08-06 06:02:58 【问题描述】:

我在我的应用程序中使用 django rest 框架。鉴于,对于 get query ,我以查询集的形式获取模型列表并尝试传递给我的 Response()

organizationViews.py

 def get(self,request):
    user = self.request.user
    result = OrganizationModel.object.all()
     serializer = OrganizationSerializer("json", list(result), many=True)
     return Response(serializer, status=status.HTTP_200_OK)

organizationModel.py

class OrganizationManager(models.Manager):
    def create_organization(self, _name):
        org = self.model( name = _name)
        org.save(using=self._db)
        return org


class Organization(BaseModel):
    name = models.CharField(_('organization'), max_length=100,       blank=True,unique=True)

def as_json(self):
    return dict(
        id=self.id,
        org_name=self.name)

object = OrganizationManager()

class Meta(BaseModel.Meta):
    db_table = 'organizations'
    verbose_name = _('organization')
    verbose_name_plural = _('organizations')

def __str__(self):
    return self.name

我收到以下错误:

Traceback (most recent call last):
 File "/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/core/handlers/base.py", line 174, in get_response
 response = self.process_exception_by_middleware(e, request)
  File "/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/core/handlers/base.py", line 172, in get_response
response = response.render()
  File "/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/template/response.py", line 160, in render
self.content = self.rendered_content
File "/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/response.py", line 71, in rendered_content
ret = renderer.render(self.data, media_type, context)
File "/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/renderers.py", line 104, in render
separators=separators
 File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/__init__.py", line 237, in dumps
**kw).encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/utils/encoders.py", line 64, in default
 return super(JSONEncoder, self).default(obj)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/encoder.py", line 180, in default
 raise TypeError(repr(o) + " is not JSON serializable")
 TypeError: OrganizationSerializer('json', [<Organization: zeotap>, <Organization: movial>, <Organization: Redbull>, <Organization: mogey>, <Organization: vizury>], many=True):
id = IntegerField()
name = CharField() is not JSON serializable

如果我在 get call 中执行以下操作:

serialized_q= json.dumps(list(queryset), cls=DjangoJSONEncoder)
return Response(serialized_q, status=status.HTTP_200_OK)

我没有收到错误,但结果类似于以下内容:

 "[\"id\": 1, \"soft_delete\": false, \"created_at\": \"2016-04-14T13:35:21.636Z\", \"name\": \"org1\", \"updated_at\": \"2016-04-14T13:35:21.636Z\", 
  \"id\": 4, \"soft_delete\": false, \"created_at\": \"2016-04-14T13:37:02.230Z\", \"name\": \"org2\", \"updated_at\": \"2016-04-14T13:37:02.230Z\"]"

我应该如何将查询集传递给响应方法?

【问题讨论】:

【参考方案1】:

我认为您只能使用序列化程序来序列化单个模型。所以而不是:

serializer = OrganizationSerializer("json", list(result), many=True)

试试:

data = [
    OrganizationSerializer(model).data
    for model in result
]

那么就:

return Response(data)

见:http://www.django-rest-framework.org/api-guide/serializers/#serializing-objects

【讨论】:

抱歉,换一个试试 仍然给出以下内容:"[\"id\": 1, \"soft_delete\": false, \"created_at\": \"2016-04-14T13:35:21.636Z \", \"name\": \"org1\", \"updated_at\": \"2016-04-14T13:35:21.636Z\", \"id\": 4, \"soft_delete\ ": false, \"created_at\": \"2016-04-14T13:37:02.230Z\", \"name\": \"org2\", \"updated_at\": \"2016-04-14T13 :37:02.230Z\"]" 这对我来说可能是正确的......你期待什么输出? 这只是转义出现在 JSON 字符串中的 " - 我不确定你在做什么来以这种方式查看信息,但对我来说这看起来像是一个有效的 JSON 字符串。如果你打印它,例如,你不会看到 \s 不,我正在使用 rest 客户端来测试我的 api。因此,作为回应,我得到了以下信息。意味着我在某处将字符串/字典转换为 JSON,因此上述方式不正确。 "[\"id\": 1, \"soft_delete\": false, \"updated_at\": \"2016-04-14T13:35:21.636Z\", \"created_at\": \"2016- 04-14T13:35:21.636Z\", \"name\": \"org1\", \"id\": 4, \"soft_delete\": false, \"updated_at\": \"2016 -04-14T13:37:02.230Z\", \"created_at\": \"2016-04-14T13:37:02.230Z\", \"名称\": \"org2\"]"【参考方案2】:

您并不想重写 get 方法,您最好重写 get_queryset;

class ViewSet(ModelViewSet):
    queryset = Model.objects.all()
    serializer_class = ModelSerializer

    def get_queryset(self): #this method is called inside of get
        queryset = self.queryset.filter(doyourfiltering=True)
        return queryset

你可以直接在这里返回一个查询集,Django 会为你序列化它。您可以通过 self.request 访问请求。

【讨论】:

以上是关于Django Rest 框架:将查询集传递给 Response()的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django 的 ORM 和 Django Rest Framework 序列化嵌套关系的查询集的正确方法?

如何从序列化器字段订购 django rest 框架查询集?

Django Rest 框架 - APIView 分页

有啥方法可以将过滤后的查询集传递给 Django 分页?

将视图中的 Django 查询集传递给模板

通过 JSON 将 Django 数据库查询集传递给 Highcharts