Using django_filter and datetimeinput as a datepicker, I am trying to add a date and time input, a FROM, and TO fields.
I have only been able to use a dateinput with just one field from django forms or from django filter DateTimeFromToRangeFilter without the date picker showing (just manual text entry).
Here is my filter_model.py for the one field with a date picker.
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']
Picture shows a clickable date picker popup.
Here is my filter_model.py for the two fields, FROM and TO without a date picker.
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'})
}
Picture below shows a manual text input without a datepicker popup.
Here is my template file although I didn't alter it much when trying the two approaches above. 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>
I did look into a variety of sources on here and elsewhere. I tried using MultiWidget and jQuery but didn't get those working yet. Thoughts? Thanks in advance.
I was able to solve it using no external dependencies (no jquery), just used datetime-local input and DateTimeFromToRangeFilter with Range widget. Perhaps not the most ideal solution, but it is one way to do this.
My model, filter, view, and template codes are below.
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>