所以,我有一个来自输入字段的日期,以及一个日期到输入字段。当我通过日期范围时,它工作正常。但是当我尝试将一个或两个留空时,要获取所有项目或部分项目时,它会产生ValueError:当我尝试创建默认的空字符串时,不能使用None作为查询值或格式错误。
def report(self, request):
date_from = query['date_from'] if query['date_from'] else None
date_to = query['date_to'] if query['date_to'] else None
queryset = Client.objects.filter(
client_code__in=clients,
account__note__creation_time__gte=date_from,
account__note__creation_time__lte=date_to,
)
为了给出更好的上下文,如果我将两个字段都留空,我应该从头到尾获取所有项目,如果我从字段填写日期但是将日期留给字段为空,我应该从日期到现在都获得所有项目。如果我有从日期到现场购买空日期的日期,我应该从开始到日期到达。
懒得找到一个有效但不太满意的解决方案。如果有人发现更好的东西可以随意分享。
query = Q()
if clients:
clients = clients.split(',')
query &= Q(client_code__in=clients)
if date_from:
query &= Q(account__note__creation_time__gte=date_from)
if date_to:
query &= Q(account__note__creation_time__lte=date_to)
Client.objects.filter(query)
答案 0 :(得分:0)
如果您在查询集上放置了一个过滤器,则必须为该过滤器提供有效值.Dangoo无法猜测您实际上并不想要过滤器...
但是有一些方法可以让它看起来更好看,例如:
qs = Client.objects.all()
if date_from:
qs = qs.filter(account__note__creation_time__gte=date_from)
if date_to:
qs = qs.filter(account__note__creation_time__lte=date_to)
# etc etc for all your AND queries.
# but for OR type queries you need to use Q objects.
当您使用Client.objects.all
创建查询集时,它实际上并没有立即转到数据库并获取对象。因此,您可以通过在其上添加其他过滤器来修改该查询集,以限制结果。您可以使用所有不同的查询集方法..例如order_by()
,fetch_related()
等..直到查询集是您想要的方式。在您尝试通过迭代查询集来读取对象之前,它实际上不会执行任何SQL,例如:
# now it will go to the database and get the objects based on your filters.
for instance in qs:
print instance
所以你看,在这种情况下,你的所有过滤器都在缩小搜索范围(它们都是和“一起”),不需要使用Q(),这样可以减少输入更清晰的代码。但是,如果您正在使用OR逻辑进行查询,或者您可能将相同的查询应用于多个查询集,那么您需要使用Q类来形成该查询。