[英]Django: Queryset object filter, against another object's time range
[英]How to filter queryset against time in django with custom timezone?
我知道這個問題看起來很愚蠢,但是由於某種原因,當我將TIME_ZONE = 'UTC'
更改為'TIME_ZONE ='Asia / Kolkata'時,為什么我的django應用程序無法返回正確的過濾結果。 其他所有工作都很好,但是當我將時區更改為本地時區時,它沒有給出任何錯誤,但是views.py中的函數也給出了0個匹配結果。
這個問題也與此問題有關 。
這是我在views.py中導入Itembatch模型中的數據的功能:
@login_required
def upload_batch(request):
template_name = 'classroom/teachers/upload.html'
prompt = {'order':'Order of csv should be first_name, last_name, email, ip_address, message'}
if request.method == "GET":
return render(request,template_name,prompt)
csv_file = request.FILES['file']
data_set = csv_file.read().decode('UTF-8')
io_string = io.StringIO(data_set)
next(io_string)
uploaded_by = request.user
for column in csv.reader(io_string,delimiter=',',quotechar='|'):
_, created = ItemBatch.objects.update_or_create(
name = column[0],
pid = column[1],
quantity = column[2],
length = column[3],
width = column[4],
height = column[5],
volume = column[6],
weight = column[7],
truck_type = column[8],
origin = column[9],
destination = column[10],
uploaded_by = uploaded_by
)
context = {}
return render(request,template_name,context)
這是我在views.py中渲染對象的功能:
@method_decorator([login_required, teacher_required], name='dispatch')
class UploadedItems(ListView):
model = ItemBatch
ordering = ('name',)
context_object_name = 'quizzes'
template_name = 'classroom/teachers/item_list.html'
def get_queryset (self):
latest_item = ItemBatch.objects.latest('time')
return ItemBatch.objects.filter(time__date=latest_item.time.date(),
time__hour=latest_item.time.hour, time__minute=latest_item.time.minute)
這是模型:
# item upload
class ItemBatch(models.Model):
# uploaded_by = models.ForeignKey(Teacher, on_delete=models.CASCADE, related_name='uploaded_by')
ttypes =(('Open','Open'),('Container','Container'),('Trailer','Trailer'),('All','All'))
uploaded_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='uploaded_by')
name = models.CharField(max_length=30)
pid = models.CharField(max_length=30)
quantity = models.CharField(max_length=30)
length = models.CharField(max_length=100, blank=True)
width = models.CharField(max_length=100, blank=True)
height = models.CharField(max_length=100, blank=True)
volume = models.CharField(max_length=100, blank=True)
weight = models.CharField(max_length=100, blank=True)
truck_type = models.CharField(max_length=255,default=0, choices=ttypes)
origin = models.CharField(max_length=100, blank=True)
destination = models.CharField(max_length=100, blank=True)
time = models.DateTimeField(max_length=100, blank=True,default=now)
def __str__ (self):
return self.name
這是我的模型數據庫:
一位SO用戶建議我應該嘗試類似的方法,但是它也不起作用。
latest_item = ItemBatch.objects.latest('time')
from django.conf import settings
settings.USE_TZ = False
latest_items = ItemBatch.objects.filter(time__date=latest_item.time.date(), time__hour=latest_item.time.hour, time__minute=latest_item.time.minute)
settings.USE_TZ = True
問題是__date
, __hour
和__minute
使用的是當前時區(無論您定義為settings.TIME_ZONE
)。 而從數據庫中獲取的latest
的python datetime
對象始終是UTC。
時區感知時要記住的事情是:Django傳遞的所有datetime
對象都位於UTC中。 通常僅在在模板中顯示這些日期時間(呈現給用戶)或從表單接收輸入值(來自用戶的輸入)時才使用時區。
Trunc
和Extract
數據庫函數是這里的例外, __date
, __hour
和__minute
是其快捷方式。 他們使用settings.TIME_ZONE
除非您將tzinfo
顯式設置為None
或UTC
。
因此,兩個查詢都需要處於相同的時區上下文中。 最簡單的方法是在數據庫級別完成整個操作:
from django.db.models.functions import Trunc
from django.db.models import DateTimeField, Subquery
latest = ItemBatch.objects.order_by('-time').annotate(truncated_time=Trunc(
'time', 'minute', output_field=DateTimeField())
qs = ItemBatch.objects.annotate(truncated_time=Trunc(
'time', 'minute', output_field=DateTimeField()))\
.filter(truncated_time=Subquery(latest.values('truncated_time')[:1]))
注意:確保您的查詢集不包含字段為NULL
任何行(在您的情況下,這是不可能的,因為time
不能為NULL
),這將在對其調用Trunc
時引發異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.