根据最新时间戳和 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()
我正试图在我的通用 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()