【问题标题】:combine django-filter DateTimeFromToRangeFilter and DateTimeInput(datepicker)结合 django-filter DateTimeFromToRangeFilter 和 DateTimeInput(datepicker)
【发布时间】:2019-07-16 10:52:51
【问题描述】:

使用django_filterdatetimeinput 作为日期选择器,我正在尝试添加日期和时间输入、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,但还没有让它们工作。想法?提前致谢。

【问题讨论】:

    标签: python jquery django datepicker django-filter


    【解决方案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_1RangeWidget 创建的“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 %}">&laquo; 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 &raquo;</a>
                      {% endif %}
                  </span>
              </div> 
          </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-13
        • 2015-08-14
        • 1970-01-01
        • 1970-01-01
        • 2019-12-31
        • 1970-01-01
        • 2016-05-17
        相关资源
        最近更新 更多