根据最新时间戳和 Q 查找字段过滤 API 列表视图查询集

Filtering an API List View queryset according to latest timestamp AND Q lookup fields

我正试图在我的通用 API 列表视图中覆盖我的 get_queryset 方法。我想通过两个字段查询并获取最新的项目。

更具体地说,我想按项目名称和图表名称进行查询,并仅获取最新的元素。

我正在尝试使用 Q 查找字段实现此目的,如下所示:

class ListGraphDataAPI(ListAPIView):
    serializer_class    = GraphSerializer


    def get_queryset(self, *args, **kwargs):
        queryset_list = Graph.objects.all()
        query = self.request.GET.get("q")
        if query:
            queryset_list = queryset_list.filter(
                Q(name__icontains=query)&
                Q(project__graph__name__exact=query)
            ).distinct()

        return queryset_list

到目前为止,我可以按图表名称进行过滤。 Q(project__graph__name__exact=query) 这一行什么也没做。问题是它是外键关系。

像这样:

class Graph(models.Model):
    project         = models.ForeignKey(Project, on_delete=models.CASCADE)
    name            = models.CharField(max_length=120, blank=True)
    description     = models.CharField(max_length=400, blank=True)
    timestamp       = models.DateTimeField(auto_now=True, blank=True)

    def __str__(self):
        return self.name

    @property
    def nodes(self):
        return self.node_set.all()

    @property
    def edges(self):
        return self.edge_set.all()

在我的 URL 中输入 http://localhost:8000/graph-data/list/graph/?q=Graph2&q=project2

我的数据结构(未过滤)如下所示:

[
    {
        "project": "project1",
        "name": "Graph1",
        "description": "Graph belongs to Projekt1",
        "nodes": [
            {
                "id": 43,
                "name": "25",
                "graph": 94
            }
        ],
        "edges": [
            {
                "id": 24,
                "name": "EdgeForGraph1",
                "graph": 94,
                "source": 43,
                "target": 43
            }
        ]
    },
    {
        "project": "project1",
        "name": "Graph1",
        "description": "Graph belongs to Projekt1",
        "nodes": [
            {
                "id": 44,
                "name": "25",
                "graph": 95
            }
        ],
        "edges": [
            {
                "id": 25,
                "name": "EdgeForGraph1",
                "graph": 95,
                "source": 44,
                "target": 44
            }
        ]
    },

我用第二个过滤器尝试了很多东西,如下所示:

project__graph__icontains=query
project__graph__name=query

我还尝试按日期过滤 我尝试了 latest 方法,但到目前为止无法正常工作。

当然非常感谢任何帮助!非常感谢

啊,也许重要的是我的项目模型将名称作为主键(我知道,不好的做法)


class Project(models.Model):
    project_name            = models.CharField(max_length=120, primary_key=True, unique=True)
    start_date              = models.DateTimeField(auto_now=False, null=True, blank=True)
    end_date    

也许子句 order_by() 有帮助? 如果你想要第一个,你可以使用 .first().

https://docs.djangoproject.com/en/2.2/ref/models/querysets/#django.db.models.query.QuerySet.order_by

类似于:

queryset_list = queryset_list.filter(
    Q(name__icontains=query)&
    Q(project__graph__name__exact=query)
).distinct().order_by('project__graph__timestamp').first()

但我在你的问题中看到你这样做 ?q=Graph2&q=project2,所以 2 个参数的名称相同。你可以做 ?g=Graph2&p=project2 然后:

def get_queryset(self, *args, **kwargs):
    param_graph = self.request.GET.get("g")
    param_project = self.request.GET.get("p")
    if param_graph is null or param_project is null:
        return Graph.objects.all().order_by('timestamp').first()

    return Graph.objects.filter(
        Q(name__icontains=param_graph)&
        Q(project__name__icontains=param_project)
    ).order_by('timestamp', 'project__timestamp').first()