將文件的日期作爲文本存儲是一種不好的做法。它不便攜式,而不是django查詢api友好,並且不友好。
即使不是所有日期都需要,您也可以將所有日期存儲在數據庫中。例如,即使您只需要日期,也可以使用Oracle stores date and time in dates。
然後您可以使用DateField
+「ChoiceField
」來存儲partialdate和相關零件信息。例如:2015-02-01在月份級別截斷。 2015-02-28全日制。 2015-01-01在年級截斷。代碼:
class Item(models.Model):
PARTIAL_YEAR='%Y'
PARTIAL_MONTH='%Y-%m'
PARTIAL_DAY='%Y-%m-%d'
PARTIAL_CHOICES = (
(PARTIAL_YEAR, 'Year'),
(PARTIAL_MONTH, 'Month'),
(PARTIAL_DAY, 'Day'),
)
partial_date_date = models.DateField()
partial_date_part = models.CharField('Date part',
choices=PARTIAL_CHOICES,
max_length=10,)
驗證這兩個領域將由各自己的部件進行驗證。您可以添加表單清理(Cleaning and validating fields that depend on each other)或model clean驗證級別。
Quering容易使使用Q objects空調查詢:
q_is_year = q(partial_date_part = Item.PARTIAL_YEAR)
q_by_year = q(partial_date_date__year = 2015)
q_is_month = q(partial_date_part = Item.PARTIAL_MONTH)
q_by_month = q(partial_date_date__year = 2105)
q_by_month &= q(partial_date_date__month = 2)
qs = Item.objects.filter(q_is_year&q_by_year | q_is_month&q_by_month)
渲染顯示爲了模板呈現:
<p>{{item.partial_date_date|date:item.partial_date_part}}</p>
渲染形式要渲染表單控件,您可以使用JavaScript更改UI並幫助用戶輸入數據:
date type: (*) Year () Month () Day
date: [ change form widget dynamically ]
您可以發送3個窗口小部件控件,以一次形成並顯示一個窗口小部件。更改更改廣播日期類型選擇的可見性。我用MultiWidget。
8月13日與EDITED所有示例代碼:
models.py
from django.db import models
from datetime import date
class Item(models.Model):
PARTIAL_YEAR='%Y'
PARTIAL_MONTH='%Y-%m'
PARTIAL_DAY='%Y-%m-%d'
PARTIAL_CHOICES = (
(PARTIAL_YEAR, 'Year'),
(PARTIAL_MONTH, 'Month'),
(PARTIAL_DAY, 'Day'),
)
partial_date_part = models.CharField('Date part',
choices=PARTIAL_CHOICES,
max_length=10,)
partial_date_date = models.DateField()
some_comment = models.CharField('Comment', max_length=100,)
def save(self, *args, **kwargs):
if self.partial_date_part==self.PARTIAL_YEAR:
self.partial_date_date = date(self.partial_date_date.year, 1, 1)
elif self.partial_date_part==self.PARTIAL_MONTH:
self.partial_date_date = date(self.partial_date_date.year,
self.partial_date_date.month, 1)
super(Item, self).save(*args, **kwargs)
forms.py
from django import forms
from django.forms import widgets
from datetime import date
class DateSelectorWidget(widgets.MultiWidget):
def __init__(self, attrs=None):
days = [(d, d) for d in range(1,32)]
months = [(m, m) for m in range(1,13)]
years = [(year, year) for year in (2011, 2012, 2013)]
_widgets = (
widgets.Select(attrs=attrs, choices=days),
widgets.Select(attrs=attrs, choices=months),
widgets.Select(attrs=attrs, choices=years),
)
super(DateSelectorWidget, self).__init__(_widgets, attrs)
def decompress(self, value):
if value:
return [value.day, value.month, value.year]
return [None, None, None]
def format_output(self, rendered_widgets):
return ''.join(rendered_widgets)
def value_from_datadict(self, data, files, name):
datelist = [
widget.value_from_datadict(data, files, name + '_%s' % i)
for i, widget in enumerate(self.widgets)]
D = date(
day=int(datelist[0]),month=int(datelist[1]),year=int(datelist[2]),
)
return D
class ItemForm(forms.Form):
partial_date_part = forms.CharField(widget=forms.RadioSelect)
partial_date_date = DateSelectorWidget()
view.py
from django.http import HttpResponseRedirect
from django.views.generic import View
from models import Item
from django.forms.models import modelform_factory
from .forms import DateSelectorWidget
from django import forms
from django.forms import widgets
class MyDatAppView(View):
form_class = modelform_factory(Item ,
exclude=[],
widgets={ 'partial_date_date':
DateSelectorWidget() ,})
initial = {'some_comment': '-*-', }
template_name = 'form.html'
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
m=form.save()
return HttpResponseRedirect('/')
return render(request, self.template_name, {'form': form})
選定部分的變化時,應在模板隱藏/顯示日期部分字段添加的JavaScript。
爲什麼要使用DateField?這聽起來像你只是想使用Python的'datetime'模塊來驗證一個日期作爲其部分的總和。 – rnevius
非常感謝你的回答。 – danihp