【发布时间】:2019-01-22 10:38:13
【问题描述】:
我正在尝试为我的模型编写搜索功能。 客户具有以下字段:
cstid = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=35)
age=models.IntegerField()
gender = models.CharField(max_length=10, default='')
mobile = models.CharField(max_length=15, default='')
email = models.CharField(max_length=50, default='')
address = models.CharField(max_length=80, default='')
city = models.CharField(max_length=25, default='')
我的 html 表单将通过 POST 通过对 django 的 ajax 调用提交以下数据:
var data = {
"name": name,
"age": age,
"email": email,
"address": address,
"phone": phone,
"city": city
};
data = $(this).serialize() + "&" + $.param(data);
这些将在 django 视图中进行验证,并执行搜索查询,如下所示:
def searchpat_for_docwise_appt (request):
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
from django.db.models import CharField
from django.db.models.functions import Lower
CharField.register_lookup(Lower, "lower")
if request.method == 'POST':
name = request.POST.get('name')
age = request.POST.get('age')
# gender = request.POST.get('gender')
phone = request.POST.get('phone')
email = request.POST.get('email').lower()
address = request.POST.get('address')
city = request.POST.get('city')
if age.isdigit():
ANDSearchResult = customer.objects.filter(name__lower__contains=name.lower(), age=age, mobile__contains=phone, email__lower__contains=email.lower(
), address__lower__contains=address.lower(), city__lower__contains=city.lower())
else:
ANDSearchResult = customer.objects.filter(name__lower__contains=name.lower(), mobile__contains=phone, email__lower__contains=email.lower(
), address__lower__contains=address.lower(), city__lower__contains=city.lower())
if len(ANDSearchResult) < 1:
errmsg = 'No search results for AND search'
print("Error message is <%s>" % errmsg)
else:
print ("ANDSearchResult is <%s>" % ANDSearchResult)
errmsg = ''
if age.isdigit():
ORSearchResult = customer.objects.filter(
Q(name__lower__contains=name.lower()) | Q(age=age) | Q(
mobile__contains=phone) | Q(email__lower__contains=email.lower()) | Q(address__lower__contains=address.lower()) | Q(city__lower__contains=city.lower()))
else:
ORSearchResult = customer.objects.filter(
Q(name__lower__contains=name.lower()) | Q(
mobile__contains=phone) | Q(email__lower__contains=email.lower()) | Q(address__lower__contains=address.lower()) | Q(city__lower__contains=city.lower()))
if len(ORSearchResult) < 1:
errmsg = errmsg + 'No search results for OR search'
print("Error message is <%s>" % errmsg)
else:
print ("ORSearchResult is <%s>" % ORSearchResult)
print(errmsg)
return HttpResponse(errmsg)
else:
errmsg = 'No correct POST request. No valid response.'
print("Error message is <%s>" % errmsg)
return HttpResponse(errmsg)
正如您在上面提到的,我同时执行两个不同的查询。我想要一个类似于查询的 AND 运算符,其中搜索必须满足所有输入参数。我还需要一个 OR 运算符,如果任何字段与相应字段的输入字符串匹配,它应该提供结果。我的意思是,如果一个病人的名字是 56 岁的 Jeff,一个 23 岁的病人 Kane;我在 name 字段中输入 jef,在 age 字段中输入 23,两者都应该被列出。
当搜索框中有空字符串时,就会出现问题。使用空字符串的 OR 搜索将所有对象作为结果。显然,我不想仅仅因为我的搜索字符串为空就返回患者记录。
除了像这样检查所有搜索查询组合的冗长解决方案:
if (name != '' and age != '' and phone != '' and email != '' and address != '' and city != '':
ORSearchResult = customer.objects.filter(Q(name__lower__contains=name.lower()) | Q(age=age) | Q(mobile__contains=phone) | Q(email__lower__contains=email.lower()) | Q(address__lower__contains=address.lower()) | Q(city__lower__contains=city.lower()))
elif (age != '' and phone != '' and email != '' and address != '' and city != '':
ORSearchResult = customer.objects.filter(Q(age=age) | Q(mobile__contains=phone) | Q(email__lower__contains=email.lower()) | Q(address__lower__contains=address.lower()) | Q(city__lower__contains=city.lower()))
elif (phone != '' and email != '' and address != '' and city != '':
ORSearchResult = customer.objects.filter(Q(mobile__contains=phone) | Q(email__lower__contains=email.lower()) | Q(address__lower__contains=address.lower()) | Q(city__lower__contains=city.lower()))
.... Other permutations ...
什么是更好的解决方案? 一个明显的想法是,尝试将这些过滤器编译成一个变量并将其传递给过滤器函数。我在正确的轨道上吗?我该怎么做?
【问题讨论】:
标签: python django django-models django-filter