用于查询数据库的 Django 表单。是否需要form.py以及如何留空查询?
Django form for querying database. Is form.py needed and how to leave fields empty for query?
我想要一个输入表单,用户可以在其中输入 incident_id
或 equipment_id
或两者。我现在遇到的问题是,例如,如果我填写 incident_id
并将 equipment_id
留空,即使 incident_id
找到匹配项,查询也将 return 没有命中,因为我的查询在搜索中使用空白 equipment_id
。我如何设置它,以便当我将一个字段留空时,它不会在查询中使用它?我需要验证这些数据吗?我不会将其中的任何内容插入数据库。
我知道Django表单使用POST,但在这种情况下我觉得GET更合适,这意味着我不必使用Django表单,但这是否意味着我也没有验证数据?还是我应该只使用 POST 并使用 Django 表单验证该数据?对不起,这太概念化了。我在网上找不到很多好的答案。
model.py
from django.db import models
class Incident(models.Model):
incident_id = models.CharField(max_length=1000, blank=True)
equipment_id = models.ForeignKey(Equipment, blank=True)
class Equipment(models.Model):
equipment_id = models.CharField(primary_key=True, max_length=100)
manufacturer = models.ForeignKey(Manufacturer)
equipment_category = models.ForeignKey(Equipment_Category)
validated= models.BooleanField(default=True)
in_service_date = models.DateTimeField('in service date', default=timezone.now)
view.py
@login_required
def search_incidents_query(request):
if request.method == 'GET':
incident_id_query = request.GET.get('incident_id')
equipment_id_query = request.GET.get('equipment_id')
try:
incident_id = str(incident_id_query)
except ValueError:
incident_id = None
try:
equipment_id = str(equipment_id_query)
except ValueError:
username = None
list = [incident_id,equipment_id]
if all(x is None for x in list): #check if `list` contains only None
incident_list = None #this in case the query comes back empty
else: #perform query
incident_list = Incident.objects.filter(incident_id=incident_id, equipment_id=equipment_id)
)
return render(request, 'search_incidents_query.html', {
'incident_list' : incident_list
})
search_incidents_query.html
{% extends "base.html" %}
{% load widget_tweaks %}
{% block content %}
<br>
<div class="container-fluid">
<!-----INPUT FORM------------------->
<form method='GET' action='/search_incidents/'>
<div class="row">
<div class="form-group col-md-3">
<label>Incident ID</label>
<input type="text" name="incident_id" value="{{ incident_id_query }}" class="form-control"/>
</div>
<div class="form-group col-md-3">
<label>Equipment ID</label>
<input type="text" name="equipment" value="{{ equipment_id_query }}" class="form-control"/>
</div>
</div>
</form>
</div>
{% endblock %}
查询
对于类似的查询,您应该使用 Q 对象。
from django.db.models import Q
Incident.objects.filter(
Q(incident_id=incident_id) | Q(equipment_id=equipment_id)
)
更多关于 Q objects。
此外,IMO 此代码需要以某种形式存在 class。如果是我,我会把这段代码放在一些
形式
class IncidentSearchForm(forms.Form):
incident = forms.CharField(required=False)
# ModelChoiceField because we want django to do the validation for us
# TextInput because the default widget is a select tag
equipment = forms.ModelChoiceField(Equipment.objects.all(), required=False, widget=forms.TextInput) # TextInput because
def clean(self):
# I'd use the clean method to force the user to provide either an incident or equipment value
def search(self):
return Incident.objects.filter(
Q(incident_id=self.cleaned_data['incident']) |
Q(equipment_id=self.cleaned_data['equipment'])
)
景色
- 您为什么不使用 Class 基于视图?
username = None
。哇?
您应该使用表格,因为never trust user input。
@login_required
def search_incidents_query(request):
form = IncidentSearchForm(request.GET or None)
incident_list = None
if 'equipment' in request.GET or 'incident' in request.GET:
incident_list = None # Or maybe Incident.objects.none()
if form.is_valid():
incident_list = form.search()
return render(request, 'search_incidents_query.html', {'form' : form})
模板
<form method='GET' action='/search_incidents/'>
<div class="row">
<div class="form-group col-md-3">
{{ form.incident }}
</div>
<div class="form-group col-md-3">
{{ form.equipment }}
</div>
</div>
<input type="submit" />
</form>
您可以使用表单上的小部件将 form-control
class 添加到字段中。
我想要一个输入表单,用户可以在其中输入 incident_id
或 equipment_id
或两者。我现在遇到的问题是,例如,如果我填写 incident_id
并将 equipment_id
留空,即使 incident_id
找到匹配项,查询也将 return 没有命中,因为我的查询在搜索中使用空白 equipment_id
。我如何设置它,以便当我将一个字段留空时,它不会在查询中使用它?我需要验证这些数据吗?我不会将其中的任何内容插入数据库。
我知道Django表单使用POST,但在这种情况下我觉得GET更合适,这意味着我不必使用Django表单,但这是否意味着我也没有验证数据?还是我应该只使用 POST 并使用 Django 表单验证该数据?对不起,这太概念化了。我在网上找不到很多好的答案。
model.py
from django.db import models
class Incident(models.Model):
incident_id = models.CharField(max_length=1000, blank=True)
equipment_id = models.ForeignKey(Equipment, blank=True)
class Equipment(models.Model):
equipment_id = models.CharField(primary_key=True, max_length=100)
manufacturer = models.ForeignKey(Manufacturer)
equipment_category = models.ForeignKey(Equipment_Category)
validated= models.BooleanField(default=True)
in_service_date = models.DateTimeField('in service date', default=timezone.now)
view.py
@login_required
def search_incidents_query(request):
if request.method == 'GET':
incident_id_query = request.GET.get('incident_id')
equipment_id_query = request.GET.get('equipment_id')
try:
incident_id = str(incident_id_query)
except ValueError:
incident_id = None
try:
equipment_id = str(equipment_id_query)
except ValueError:
username = None
list = [incident_id,equipment_id]
if all(x is None for x in list): #check if `list` contains only None
incident_list = None #this in case the query comes back empty
else: #perform query
incident_list = Incident.objects.filter(incident_id=incident_id, equipment_id=equipment_id)
)
return render(request, 'search_incidents_query.html', {
'incident_list' : incident_list
})
search_incidents_query.html
{% extends "base.html" %}
{% load widget_tweaks %}
{% block content %}
<br>
<div class="container-fluid">
<!-----INPUT FORM------------------->
<form method='GET' action='/search_incidents/'>
<div class="row">
<div class="form-group col-md-3">
<label>Incident ID</label>
<input type="text" name="incident_id" value="{{ incident_id_query }}" class="form-control"/>
</div>
<div class="form-group col-md-3">
<label>Equipment ID</label>
<input type="text" name="equipment" value="{{ equipment_id_query }}" class="form-control"/>
</div>
</div>
</form>
</div>
{% endblock %}
查询
对于类似的查询,您应该使用 Q 对象。
from django.db.models import Q
Incident.objects.filter(
Q(incident_id=incident_id) | Q(equipment_id=equipment_id)
)
更多关于 Q objects。
此外,IMO 此代码需要以某种形式存在 class。如果是我,我会把这段代码放在一些
形式
class IncidentSearchForm(forms.Form):
incident = forms.CharField(required=False)
# ModelChoiceField because we want django to do the validation for us
# TextInput because the default widget is a select tag
equipment = forms.ModelChoiceField(Equipment.objects.all(), required=False, widget=forms.TextInput) # TextInput because
def clean(self):
# I'd use the clean method to force the user to provide either an incident or equipment value
def search(self):
return Incident.objects.filter(
Q(incident_id=self.cleaned_data['incident']) |
Q(equipment_id=self.cleaned_data['equipment'])
)
景色
- 您为什么不使用 Class 基于视图?
username = None
。哇?
您应该使用表格,因为never trust user input。
@login_required
def search_incidents_query(request):
form = IncidentSearchForm(request.GET or None)
incident_list = None
if 'equipment' in request.GET or 'incident' in request.GET:
incident_list = None # Or maybe Incident.objects.none()
if form.is_valid():
incident_list = form.search()
return render(request, 'search_incidents_query.html', {'form' : form})
模板
<form method='GET' action='/search_incidents/'>
<div class="row">
<div class="form-group col-md-3">
{{ form.incident }}
</div>
<div class="form-group col-md-3">
{{ form.equipment }}
</div>
</div>
<input type="submit" />
</form>
您可以使用表单上的小部件将 form-control
class 添加到字段中。