结合 django-filter DateTimeFromToRangeFilter 和 DateTimeInput(datepicker)
Posted
技术标签:
【中文标题】结合 django-filter DateTimeFromToRangeFilter 和 DateTimeInput(datepicker)【英文标题】:combine django-filter DateTimeFromToRangeFilter and DateTimeInput(datepicker) 【发布时间】:2019-07-16 10:52:51 【问题描述】:使用django_filter 和datetimeinput 作为日期选择器,我正在尝试添加日期和时间输入、FROM 和TO 字段。
我只能使用来自 django 表单或来自 django 过滤器DateTimeFromToRangeFilter 的一个字段的日期输入,而没有显示日期选择器(只是手动输入文本)。
这是我的 filter_model.py,用于带有日期选择器的一个字段。
from app.models.api_status import ApiStatus
import django_filters
from django import forms
class DateTimeInput(forms.DateTimeInput):
input_type = 'date'
# working solution for just 1 date field
class ApiStatusFilter(django_filters.FilterSet):
date_time = django_filters.DateFilter(
label=('With start date'),
lookup_expr=('icontains'), # use contains,
widget=DateTimeInput()
)
class Meta:
model = ApiStatus
fields = ['id', 'date_time']
图片显示了一个可点击的日期选择器弹出窗口。
这是我的 filter_model.py 两个字段,FROM 和 TO,没有日期选择器。
from app.models.api_status import ApiStatus
import django_filters
from django import forms
class DateTimeInput(forms.DateTimeInput):
input_type = 'date'
class ApiStatusFilter(django_filters.FilterSet):
date_time =django_filters.DateTimeFromToRangeFilter()
class Meta:
model = ApiStatus
fields = ['id', 'date_time']
widgets =
'date_time': forms.DateTimeInput(attrs='placeholder':'Select a date')
下图显示了没有日期选择器弹出窗口的手动文本输入。
这是我的模板文件,尽管我在尝试上述两种方法时并没有对其进行太多改动。 status_template.html
% load static %
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="% static 'css/table_styling.css' %">
<meta charset="UTF-8">
<title>Test Site</title>
% comment %
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
% endcomment %
</head>
<body>
<table>
<thead>
<tr>
% for keys in dictionarys.keys %
<th> keys </th>
% endfor %
</tr>
</thead>
<tbody>
<form method="get">
apistatus_filter.form.as_p
<button type="submit">Search</button>
% for user in dataqs.object_list %
<tr>
<td> user.id </td>
<td> user.date_time </td>
% endfor %
</form>
</tbody>
</table>
% comment % <script>
$( function()
$("#datepicker").datepicker();
);
</script> % endcomment %
</body>
</html>
我确实查看了这里和其他地方的各种来源。我尝试使用 MultiWidget 和 jQuery,但还没有让它们工作。想法?提前致谢。
【问题讨论】:
【参考方案1】:可以使用 javascript 使范围字段具有 datepicker
类。
我正在努力让 jQuery 日期选择器与来自 Django Filters 的 DateTimeFromToRangeFilter
结合使用 RangeWidget
。出于某种原因,RangeWidget
似乎不会接受class: datepicker
。
Filters.py:
dtoriginal = django_filters.DateTimeFromToRangeFilter(lookup_expr='icontains',
widget=django_filters.widgets.RangeWidget(
attrs=
'placeholder': 'yyyy-mm-dd',
,
),
label = 'Date Original'
)
我更改了我的搜索模板 html 以包含以下脚本:
<form method="get">
filter.form.as_p
<script>
$(function ()
$("id_dtoriginal_0").datepicker();
$("id_dtoriginal_1").datepicker();
);
</script>
% if filter.is_bound %
<button onclick=...></button
% endif %
</form>
其中dtoriginal
是模型中字段的名称。 _0
和_1
是RangeWidget
创建的“from”和“to”字段。
希望这会有所帮助,我花了几个小时试图通过 django-filters 弄清楚如何做到这一点,但没有运气。
【讨论】:
【参考方案2】:我能够使用没有外部依赖项(没有 jquery)来解决它,只需使用 datetime-local 输入和 DateTimeFromToRangeFilter 和 Range 小部件。也许不是最理想的解决方案,但它是一种方法。
我的模型、过滤器、视图和模板代码如下。
model.py
from app.modules.string_handler import StringHandler
from django.db.models.signals import post_save
import datetime
class ApiStatus(models.Model):
id = models.AutoField(primary_key=True)
date_time = models.DateTimeField("Date_Time", default=datetime.datetime.now(), blank=True)
class Meta:
managed = True
db_table = 'api_status'
verbose_name = 'API STATUS'
def __str__(self):
"A string representation of the model."
return f'self.id,self.token,self.date_time,self.status,self.summary,self.log'
def __unicode__(self):
return self.created_at
filter.py
from app.models.api_status import ApiStatus
import django_filters
from django import forms
class ApiStatusFilter(django_filters.FilterSet):
date_time = django_filters.DateTimeFromToRangeFilter(
lookup_expr=('icontains'),
widget=django_filters.widgets.RangeWidget(
attrs='type':'datetime-local'
)
)
class Meta:
model = ApiStatus
fields = ['id', 'date_time']
view.py
from django.shortcuts import render
from app.models.filters_model import ApiStatusFilter
from app.models.api_status import ApiStatus
import requests
from django import forms
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import urllib
from datetime import datetime, timedelta
def status(request):
apistatus_list = ApiStatus.objects.all()
request.GET2 = request.GET.copy()
if request.GET2.get('date_time_min'):
request.GET2['date_time_min'] = datetime.strptime(request.GET2['date_time_min'],"%Y-%m-%dT%H:%M").strftime("%Y-%m-%d %H:%M")
if request.GET2.get('date_time_max'):
request.GET2['date_time_max'] = datetime.strptime(request.GET2['date_time_max'],"%Y-%m-%dT%H:%M").strftime("%Y-%m-%d %H:%M")
apistatus_filter = ApiStatusFilter(request.GET2, queryset=apistatus_list)
paginator = Paginator(apistatus_filter.qs, 10)
page = request.GET.get('page')
try:
dataqs = paginator.page(page)
except PageNotAnInteger:
dataqs = paginator.page(1)
except EmptyPage:
dataqs = paginator.page(paginator.num_pages)
return render(request, 'status_page_template.html', 'table_col_DATA':all_entries_ordered, 'dictionarys': dictionarys, 'apistatus_filter': apistatus_filter, 'dataqs': dataqs, 'allobjects': apistatus_list)
template.html
% load my_templatetags %
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="% static 'css/search_form_table_styling.css' %">
<meta charset="UTF-8">
<title>TEST Site</title>
</head>
<body>
<form method="get" action="">
<div class="search_form_wrapper">
<div class="id_box">ID: apistatus_filter.form.id </div>
<div class="id_box">Date_Time: apistatus_filter.form.date_time </div>
</div>
<input type="submit" value="Submit" class="search_form_submit">
</form>
<table>
<tbody>
% for user in dataqs.object_list %
<tr>
<td> user.id </td>
<td> user.date_time </td>
</tr>
% endfor %
</tbody>
</table>
<div class="pagination">
<span>
% if dataqs.has_previous %
<a href="?% query_transform request page=1 %">« first</a>
<a href="?% query_transform request page=dataqs.previous_page_number %">previous</a>
% endif %
<span class="current">
Page dataqs.number of dataqs.paginator.num_pages .
</span>
% if dataqs.has_next %
<a href="?% query_transform request page=dataqs.next_page_number %">next</a>
<a href="?% query_transform request page=dataqs.paginator.num_pages %">last »</a>
% endif %
</span>
</div>
</body>
</html>
【讨论】:
以上是关于结合 django-filter DateTimeFromToRangeFilter 和 DateTimeInput(datepicker)的主要内容,如果未能解决你的问题,请参考以下文章