【问题标题】:Dynamic queryset with current date for a ModelChoiceField in a ModelFormModelForm 中 ModelChoiceField 的当前日期的动态查询集
【发布时间】:2016-07-09 09:10:23
【问题描述】:

我读过很多类似的问题,但没有人澄清它是在我们第一次运行服务器时启动,还是每次在浏览器中刷新页面时启动。

我有一个这样的 ModelForm:

class TestForm(ModelForm):
    field1 = ModelChoiceField(queryset=Model.objects.filter(datetime=datetime.today()))

如果我昨天运行服务器并在今天刷新页面,我仍然拥有昨天日期时间的对象。

【问题讨论】:

    标签: django modelform


    【解决方案1】:

    Starting with Django 1.9可以在查询级别获取当前时间:

    from django.db.models.functions import Now
    Model.objects.filter(datetime=Now())
    

    Now() 将在查询执行时进行评估(而不是在 Python 代码中执行 Now() 时)。但是请注意,Now() 会报告数据库服务器已知的时间。

    【讨论】:

      【解决方案2】:

      问题是您的查询集在服务器首次加载时被评估一次。

      解决方法是在表单的__init__方法中设置queryset,这样每次实例化表单时都会计算queryset。

      class TestForm(ModelForm):
          # Use the empty qs .none() here, we override it in __init__ anyway
          field1 = ModelChoiceField(queryset=Model.objects.none())
      
          def __init__(self, *args, **kwargs):
              super(TestForm, self).__init__(*args, **kwargs)
              self.fields['field1'].queryset = Model.objects.filter(datetime=datetime.today())
      

      【讨论】:

      • 这看起来不错。但是...最后一行可能是: self.fields['field1'].queryset = Model.objects.filter(datetime=datetime.today()) ?
      【解决方案3】:

      您拥有的代码将在服务器启动时运行一次。如果您希望在每次页面刷新时检查日期,您可以传递 datetime.today 函数而不是值:

      class TestForm(ModelForm):
          field1 = ModelChoiceField(queryset=Model.objects.filter(datetime=datetime.today))
      

      【讨论】:

      • 支持将可调用对象传递给查询集参数在 Django 1.7 中已弃用,并在 1.9 (release notes) 中删除。
      猜你喜欢
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-15
      • 2019-08-15
      相关资源
      最近更新 更多