Django:查询数据库的表单
Django: form to query database
我希望用户能够执行以下查询:
获取所有人员,没有博士学位,有全职合同,并在两个日期内签订合同。
在 Django 中翻译:
Contract.objects.filter(
person__is_doctor = False,
type_contract = 'full',
starting_date__gte = start_date,
ending_date__lte = end_date
)
如何制作 form/view/template 以允许用户同时输入 start_date 和 end_date 并显示结果?
型号
class Person(models.Model):
name = models.CharField(max_length=32)
surname = models.CharField(max_length=32)
address = models.CharField(max_length=32)
is_doctor = models.NullBooleanField(blank=True, verbose_name=_(u"Phd?")
TYPE_CONTRACT = (
('PT', 'Partial time'),
('FC', 'Full contract')
)
class Contract(models.Model):
person = models.ForeignKey(Person) #person hired
type_contract = models.CharField(max_length = 9, blank = True, choices = TYPE_CONTRACT)
starting_date = models.DateField(blank = True, null = True)
ending_date = models.DateField(blank = True, null = True)
这是主要思想,此外,您还必须检查 start_date 和 end_date 是否确实在 cleaned_data 中,并在使用 filter() 时考虑到这一点。
形式
class MyForm(forms.Form):
start_date = forms.DateField(initial=datetime.date.today)
end_date = forms.DateField(initial=datetime.date.today)
查看
def my_view(request):
contracts = Contract.objects.filter(person__is_doctor=False, type_contract='full')
# if this is a POST request take start_date and end_date into account
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
contracts = contracts.filter(starting_date__gte=form.cleaned_data.get('start_date'), ending_date__lte=form.cleaned_data.get('end_date'))
else:
form = MyForm()
# do everything else that you need to do before returning a response
return render_to_response('template.html', locals(), context_instance=RequestContext(request))
模板
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
{% for contract in contracts %}
{{ contract.person }}
{% endfor %}
首先,我将重构 Contract
模型以更好地封装选择,另外,为什么合同允许开始日期和结束日期为空值?从业务逻辑的角度来看,这对我来说似乎很奇怪。
class Contract(models.Model):
PT = 'Part Time'
FC = 'Full Contract'
CONTRACT_CHOICES = (
('PT', PT),
('FC', FC)
)
person = models.ForeignKey(Person)
type_contract = models.CharField(max_length=9, choices=CONTRACT_CHOICES,
default=PT)
starting_date = models.DateField()
ending_date = models.DateField()
# view
from django.shortcuts import render
from .forms import ContactForm
def filter_contracts(request):
form = ContractForm(request.POST or None)
contracts = None
if request.method == 'POST':
if form.is_valid():
# encapsulating the contract values means you don't have to
# hand-code them in the query so your code stays DRY
contracts = Contract.objects.filter(person__is_doctor=False,
type_contract=Contract.FC,
starting_date__gte=form.cleaned_data.get('starting_date'),
ending_date__lte=form.cleaned_data.get('ending_date'))
# you might want to specify an order_by here
return render(request, 'your_template.html', {'form': form,
'contracts': contracts})
# template
<form action="." enctype="application/x-www-form-urlencoded" method="post">
<ol>
{{ form.as_ul }}
</ol>
{% csrf_token %}
<button type="submit">Search</button>
{% if contracts %}
<table>
{% for contract in contracts %}
<tr>
<td>{{ contract.person }}</td>
<td>{{ contract.type_contract }}</td>
<td>{{ contract.starting_date }}</td>
<td>{{ contract.ending_date }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</form>
我希望用户能够执行以下查询:
获取所有人员,没有博士学位,有全职合同,并在两个日期内签订合同。
在 Django 中翻译:
Contract.objects.filter(
person__is_doctor = False,
type_contract = 'full',
starting_date__gte = start_date,
ending_date__lte = end_date
)
如何制作 form/view/template 以允许用户同时输入 start_date 和 end_date 并显示结果?
型号
class Person(models.Model):
name = models.CharField(max_length=32)
surname = models.CharField(max_length=32)
address = models.CharField(max_length=32)
is_doctor = models.NullBooleanField(blank=True, verbose_name=_(u"Phd?")
TYPE_CONTRACT = (
('PT', 'Partial time'),
('FC', 'Full contract')
)
class Contract(models.Model):
person = models.ForeignKey(Person) #person hired
type_contract = models.CharField(max_length = 9, blank = True, choices = TYPE_CONTRACT)
starting_date = models.DateField(blank = True, null = True)
ending_date = models.DateField(blank = True, null = True)
这是主要思想,此外,您还必须检查 start_date 和 end_date 是否确实在 cleaned_data 中,并在使用 filter() 时考虑到这一点。
形式
class MyForm(forms.Form):
start_date = forms.DateField(initial=datetime.date.today)
end_date = forms.DateField(initial=datetime.date.today)
查看
def my_view(request):
contracts = Contract.objects.filter(person__is_doctor=False, type_contract='full')
# if this is a POST request take start_date and end_date into account
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
contracts = contracts.filter(starting_date__gte=form.cleaned_data.get('start_date'), ending_date__lte=form.cleaned_data.get('end_date'))
else:
form = MyForm()
# do everything else that you need to do before returning a response
return render_to_response('template.html', locals(), context_instance=RequestContext(request))
模板
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
{% for contract in contracts %}
{{ contract.person }}
{% endfor %}
首先,我将重构 Contract
模型以更好地封装选择,另外,为什么合同允许开始日期和结束日期为空值?从业务逻辑的角度来看,这对我来说似乎很奇怪。
class Contract(models.Model):
PT = 'Part Time'
FC = 'Full Contract'
CONTRACT_CHOICES = (
('PT', PT),
('FC', FC)
)
person = models.ForeignKey(Person)
type_contract = models.CharField(max_length=9, choices=CONTRACT_CHOICES,
default=PT)
starting_date = models.DateField()
ending_date = models.DateField()
# view
from django.shortcuts import render
from .forms import ContactForm
def filter_contracts(request):
form = ContractForm(request.POST or None)
contracts = None
if request.method == 'POST':
if form.is_valid():
# encapsulating the contract values means you don't have to
# hand-code them in the query so your code stays DRY
contracts = Contract.objects.filter(person__is_doctor=False,
type_contract=Contract.FC,
starting_date__gte=form.cleaned_data.get('starting_date'),
ending_date__lte=form.cleaned_data.get('ending_date'))
# you might want to specify an order_by here
return render(request, 'your_template.html', {'form': form,
'contracts': contracts})
# template
<form action="." enctype="application/x-www-form-urlencoded" method="post">
<ol>
{{ form.as_ul }}
</ol>
{% csrf_token %}
<button type="submit">Search</button>
{% if contracts %}
<table>
{% for contract in contracts %}
<tr>
<td>{{ contract.person }}</td>
<td>{{ contract.type_contract }}</td>
<td>{{ contract.starting_date }}</td>
<td>{{ contract.ending_date }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</form>