Django 中 DateField 的 RuntimeWarning

Posted

技术标签:

【中文标题】Django 中 DateField 的 RuntimeWarning【英文标题】:RuntimeWarning for DateField in Django 【发布时间】:2019-06-11 18:00:45 【问题描述】:

您好,我正在使用日期进行搜索查询。但是我遇到了运行时错误。

RuntimeWarning:DateTimeField Jobs.job_created_on 在时区支持处于活动状态时收到了一个幼稚的日期时间 (2019-01-17 00:00:00)。

Views.py

class JobListView(LoginRequiredMixin, generic.TemplateView):
    template_name = 'admin/jobs/job.html'

    def get(self, request, *args, **kwargs):
        context = super(JobListView, self).get_context_data(**kwargs)

        if 'status' in request.GET:
            form = JobSearchForm(request.GET)

            if form.is_valid():
                status = form.cleaned_data['status']
                start_date = form.cleaned_data['start_date']
                end_date = form.cleaned_data['end_date']
                company = self.request.user.userprofile.user_company

                lookups = (Q(job_company=self.request.user.userprofile.user_company) ) 

                if start_date:
                    lookups = lookups | Q(job_created_on__gte=start_date)
                if end_date:
                    lookups = lookups | Q(job_created_on__lte=end_date)

                jobs=Jobs.objects.exclude(job_is_deleted = True).filter(lookups)

        else:
            form = JobSearchForm()
            company_name = self.request.user.userprofile.user_company
            jobs = Jobs.objects.exclude(
                                job_is_deleted = True
                            ).filter(
                                job_company=self.request.user.userprofile.user_company
                            )

        return render(request, self.template_name, 'form': form, 'jobs': jobs)

Forms.py

ACTIVE_CHOICES = (
    ('AllStatus', 'Select Status'),
    ('Active', 'Active'),
    ('InActive', 'Inactive'),
)
class JobSearchForm(forms.Form):
    start_date = forms.DateField(label=False)
    end_date = forms.DateField(label=False)
    status = forms.ChoiceField(choices=ACTIVE_CHOICES, label=False, initial="")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['start_date'].widget.attrs['placeholder'] = 'Start Date'
        self.fields['end_date'].widget.attrs['placeholder'] = 'End Date'
        # self.fields['status'].initial = 'Select Status'
        self.fields['start_date'].widget.attrs['class'] = 'job_date'
        self.fields['end_date'].widget.attrs['class'] = 'job_date'
        self.fields['start_date'].required=False
        self.fields['end_date'].required=False

Models.py - 工作模型

class Jobs(models.Model):
    job_created_on = models.DateTimeField(auto_now_add=True)
    job_created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='job_created_bys')
    job_updated_on = models.DateTimeField(auto_now=True)
    job_updated_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='job_updated_bys')
    job_is_deleted = models.BooleanField(default=False)
    job_deleted_at = models.DateTimeField(blank=True, null=True)
    ACTIVE = 'Active'
    INACTIVE = 'Inactive'
    JOB_ACTIVE_CHOICES = (
        (ACTIVE, 'Active'),
        (INACTIVE, 'Inactive'),
    )
    job_status = models.CharField(
        max_length=8,
        choices=JOB_ACTIVE_CHOICES,
        default=INACTIVE,
    )

为什么它给我运行时警告 - RuntimeWarning:DateTimeField Jobs.job_created_on 在时区支持处于活动状态时收到一个天真的日期时间 (2019-01-17 00:00:00)。

【问题讨论】:

警告实际上是针对DateTimeField(即Jobs.job_created_on),也很清楚。你有什么问题? RuntimeWarning: DateTimeField received a naive datetime的可能重复 这不是错误,而是警告。你能添加Jobs 模型定义吗? Jobs.job_created_on 字段可识别时区。因此,当您检查 job_created_on 是否大于 start_date 这是一个简单的日期字段(不知道时区,即天真)时,如果查询是由欧洲的某人或澳大利亚的某人自该日期起进行的,结果可能会有所不同job_created_on 的值可能不同(如果 job_created_on 是 2019 年 1 月 1 日 GMT+1 晚上 10 点,则澳大利亚是 2019 年 1 月 2 日上午 8 点)。为避免警告,您需要将其与时区感知日期时间进行比较。 这里我添加了 Jobs 模型,请查看 【参考方案1】:

正如@dirkgroten 突出显示的那样,您的表单将没有时区的Date 返回到模型中的时区感知DateTime。以下是使用 date 查找解决此问题的方法:

if start_date:
    lookups = lookups | Q(job_created_on__date__gte=start_date)
if end_date:
    lookups = lookups | Q(job_created_on__date__lte=end_date)

【讨论】:

以上是关于Django 中 DateField 的 RuntimeWarning的主要内容,如果未能解决你的问题,请参考以下文章

我的 django 模型 DateField 如何将 30 天添加到提供的值?

仅显示月份和年份的 Django DateField 日历?

DateField 的 Django 模型过滤器不起作用

如何在 Django DateField 中仅保留日期部分

Django rest框架DateField格式

Django 模型 DateField to_python