Django python -- ** 之后的 filter() 参数必须是一个映射,而不是 str
Django python -- filter() argument after ** must be a mapping, not str
我正在尝试在 forms.py 中动态创建查询。我将它存储为一个字符串,然后尝试过滤并 return 它,但我收到错误...
filter() argument after ** must be a mapping, not str
这是怎么回事?显然它不喜欢它。它应该是不同的数据类型吗?
forms.py
from django import forms
from django.db.models import Q
from .models import Incident
from .models import Equipment
class IncidentForm(forms.Form):
incident_id = forms.IntegerField(required=False)
equipment_id = forms.ModelChoiceField(Equipment.objects.all(), required=False, widget=forms.TextInput)
def search(self):
# cleaning the data
cust_id = self.cleaned_data.get('incident_id')
equip_id = self.cleaned_data.get('equipment_id')
user_input = [cust_id, equip_id]
# finding blank fields
i = 0
lst=[]
for x in user_input:
if x != None:
lst.append(i)
i += 1
# setting up query with non blank data
query = ""
for x in lst:
if x == 0:
query += 'Q(id=cust_id)'
if x == 1:
query += 'Q(equipment_id=equip_id)'
# replace all instances of ')' with ') & '. Also removed the last &
new_query = query.replace(")", ") & ")
new_query = new_query[:-3]
print (new_query)
return Incident.objects.filter(**new_query)
因为filter
没有将字符串作为过滤器。相反,您应该将 Q
对象或关键字过滤器(如 django 文档中所示)传递给它。在您的情况下,您可以即时创建最终查询:
query = Q()
for x in lst:
if x == 0:
query &= Q(id=cust_id)
if x == 1:
query &= Q(equipment_id=equip_id)
print (query)
return Incident.objects.filter(query)
&=
运算符创建新的 Q
对象,代表 AND
的左手边和右手边,原地。
Q
对象是实际对象。它们不是您用字符串编写的迷你语言。你应该使用:
query = Q()
for x in lst:
if x == 0:
query &= Q(id=cust_id)
if x == 1:
query &= Q(equipment_id=equip_id)
return Incident.objects.filter(query)
不过,这看起来像是一种过度设计的方法来实现您想要做的事情。怎么样:
def search(self):
cust_id = self.cleaned_data.get('incident_id')
equip_id = self.cleaned_data.get('equipment_id')
qs = Incident.objects.all()
if cust_id is not None:
qs = qs.filter(id=cust_id)
if equip_ip is not None:
qs = qs.filter(equipement_id=equip_id)
return qs
我正在尝试在 forms.py 中动态创建查询。我将它存储为一个字符串,然后尝试过滤并 return 它,但我收到错误...
filter() argument after ** must be a mapping, not str
这是怎么回事?显然它不喜欢它。它应该是不同的数据类型吗?
forms.py
from django import forms
from django.db.models import Q
from .models import Incident
from .models import Equipment
class IncidentForm(forms.Form):
incident_id = forms.IntegerField(required=False)
equipment_id = forms.ModelChoiceField(Equipment.objects.all(), required=False, widget=forms.TextInput)
def search(self):
# cleaning the data
cust_id = self.cleaned_data.get('incident_id')
equip_id = self.cleaned_data.get('equipment_id')
user_input = [cust_id, equip_id]
# finding blank fields
i = 0
lst=[]
for x in user_input:
if x != None:
lst.append(i)
i += 1
# setting up query with non blank data
query = ""
for x in lst:
if x == 0:
query += 'Q(id=cust_id)'
if x == 1:
query += 'Q(equipment_id=equip_id)'
# replace all instances of ')' with ') & '. Also removed the last &
new_query = query.replace(")", ") & ")
new_query = new_query[:-3]
print (new_query)
return Incident.objects.filter(**new_query)
因为filter
没有将字符串作为过滤器。相反,您应该将 Q
对象或关键字过滤器(如 django 文档中所示)传递给它。在您的情况下,您可以即时创建最终查询:
query = Q()
for x in lst:
if x == 0:
query &= Q(id=cust_id)
if x == 1:
query &= Q(equipment_id=equip_id)
print (query)
return Incident.objects.filter(query)
&=
运算符创建新的 Q
对象,代表 AND
的左手边和右手边,原地。
Q
对象是实际对象。它们不是您用字符串编写的迷你语言。你应该使用:
query = Q()
for x in lst:
if x == 0:
query &= Q(id=cust_id)
if x == 1:
query &= Q(equipment_id=equip_id)
return Incident.objects.filter(query)
不过,这看起来像是一种过度设计的方法来实现您想要做的事情。怎么样:
def search(self):
cust_id = self.cleaned_data.get('incident_id')
equip_id = self.cleaned_data.get('equipment_id')
qs = Incident.objects.all()
if cust_id is not None:
qs = qs.filter(id=cust_id)
if equip_ip is not None:
qs = qs.filter(equipement_id=equip_id)
return qs