python - 从 Django 中的 QuerySet 中排除对象实例的最佳方法是什么(在这种情况下 filter() 不是一个选项)?
问题描述
现在我能想到的最好的解决方案是在特定实例上单独使用 queryset.exclude(pk=instance.pk) 。
场景是我需要为几个字段过滤模型查询集,然后还要检查日期字段是否与给定值匹配。通常我只会过滤 date=mydate 但在我的情况下,我需要首先使用不同模型中存储的时区来计算日期(这就是为什么我似乎不能简单地使用过滤器的原因)
现在我的代码(它有效,但似乎是一种 hack-y 过滤方式)看起来像这样:
user_tracks = HabitTrack.objects.filter(user=user)
filtered_user_tracks = user_tracks
for t in user_tracks:
if not HabitEvent.objects.filter(user=user, track=t, date_expected=t.get_timezone_corrected_datetime_now().date(), post__isnull=True).exists():
print("Excluding ", t.track_name, " with track specific time of ", t.get_timezone_corrected_datetime_now(), "from the list of options")
filtered_user_tracks = filtered_user_tracks.exclude(pk=t.pk)
else:
print("Including ", t.track_name, " with track specific time of ", t.get_timezone_corrected_datetime_now(), "in the list of options")
对于上下文,这是我的 ModelForm 的一个片段,因此我可以将表单选择限制为仅对用户“今天”可用的选项,其中“今天”是根据用户的时区计算的。
(这也是我第一次提出关于SO的问题,所以如果需要澄清,我会尽力清理我的问题,谢谢!)
在 HabitTrack 模型中:
def get_timezone_corrected_datetime_now(self):
return datetime.now(self.timezone)
解决方案
这可能很难。django.db.models.functions.TruncDate
withfunctions.Now
可能有效,但我不知道是否可以通过F
实例更改时区。如果您知道用户的所有曲目都在同一个时区,这会使事情变得更容易。否则,在短期内,您可能必须进行非规范化HabitEvent.date_expected
,以便拥有完整的日期时间和本地化的日期。
编辑:
更好的答案
您还可以使用数据库的函数创建自己的 Func 实例。如果您使用的是 postgres,timezone(zone, timestamp)
(docs 9.9.3)可能会满足您的需求。
您的函数可能如下所示:
class LocalizedNow(Func):
function = 'timezone'
template = '%(function)s(%(expressions)s, NOW())'
然后你可以在查询中使用它:
HabitEvent.objects.filter(expected_date=LocalizedNow('track__timezone'))
推荐阅读
- angular - Angular 6:接收对象并解析它的问题
- c# - 在微服务中创建域模型和视图模型的正确方法
- javascript - Angular7 外部 Jquery 插件 - 意外的标识符
- r - 检查每个向量元素是否减少 1 或更多的函数
- javascript - Babel 继承丢失原型
- python - 如何使用 python curses 删除面板和窗口
- laravel - 使用rabbitmq在几个docker容器之间租一个订单
- jquery - jQuery - 如果类存在于文档中,并且如果它为空
- c# - 查看未在 NET Core 上呈现
- c# - WPF - 在没有设计器的情况下创建实体布局