【问题标题】:Get latest object with filter in django rest framework在 django rest 框架中使用过滤器获取最新对象
【发布时间】:2016-08-10 09:50:28
【问题描述】:

当我通过 DRF API 请求 GET 时,我想返回最新的对象。 我在views.py中试过这个:

class ListCreateNodeConfig(generics.ListCreateAPIView):
    queryset = models.NodeConfig.objects.all()
    serializer_class = serializers.NodeConfigSerializer

    def get_queryset(self):
        return self.queryset.filter(node_id=self.kwargs.get('node_pk')).latest('timestamp')

但它会抛出错误:'NodeConfig' 对象不可迭代

models.py

class NodeConfig(models.Model):  
    node_id = models.ForeignKey(Node)
    timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
    record_interval = models.IntegerField(default=0)
    lower_frequency = models.IntegerField(default=0)
    upper_frequency = models.IntegerField(default=0)

如何解决?

感谢任何建议。

【问题讨论】:

  • 应该有返回最新方法的列表。我不认为这就是在这种情况下发生的事情。
  • .filter() 返回 Queryset,根据本文档 docs.djangoproject.com/en/1.8/ref/models/querysets 可迭代。我不明白为什么它不起作用。
  • 您不应同时定义querysetget_queryset 。可能不是这里的问题 - 但仍然......所以删除queryset属性并将self.queryset...替换为models.NodeConfig.objects...
  • @ohrstrom 是的,我在没有查询集的情况下尝试过这个,但仍然没有成功:return models.NodeConfig.objects.filter(node_id=self.kwargs.get('node_pk')).latest('时间戳')
  • 问题是,该代码在纯 Django 函数中工作(不在 DRF 中)。我还可以在 Django shell 中提取最新的一个。也许我的模型有问题?我是否需要添加 Meta 类或其他一些选项?我添加了有问题的模型

标签: python django django-rest-framework


【解决方案1】:

这里的问题是latest() 方法。这不会返回查询集,而是返回单个模型实例。 (如get(...)

所以使用:

def get_queryset(self):
    return self.queryset.filter(node_id=self.kwargs.get('node_pk')).order_by('-timestamp')

因此,如果您想为单个对象设置端点,则不得使用 DRF List*views/mixins。
列表视图假定您要使用列表(=多个对象)。所以他们依赖queryset resp。 get_queryset。一个查询集显然应该是一个查询集而不是一个模型实例......

但也包括RetrieveAPIView 视图:

from rest_framework.generics import RetrieveAPIView

class LatestNodeConfigView(RetrieveAPIView):
    queryset = models.NodeConfig.objects.all()
    # add your serializer
    serializer_class = NodeConfigDetailSerializer

    def get_object(self, *args, **kwargs):
        return self.queryset.filter(node_id=kwargs.get('node_pk')).latest('timestamp')

【讨论】:

  • 是的,我想要一个模型实例(单个对象)。我也试过那个,但同样的错误。 return models.NodeConfig.objects.filter(node_id=self.kwargs.get('node_pk')).order_by('-timestamp')[0]
  • latest 和 order_by 的区别是 latest 返回单个对象,而 order_by 返回多个。所以改变这个不会影响这里的问题。
【解决方案2】:

您还可以使用 python 切片将单个对象返回到查询集中:

self
  .queryset
  .filter(node_id=self.kwargs.get('node_pk'))
  .order_by('-timestamp')[:1]

【讨论】:

    猜你喜欢
    • 2014-02-17
    • 1970-01-01
    • 2019-03-06
    • 2012-12-24
    • 2017-05-27
    • 1970-01-01
    • 2017-10-26
    • 2018-05-17
    • 2017-06-30
    相关资源
    最近更新 更多