Python Django 原生SQL迭代导致TypeError
我在用Python Django处理表单时遇到了一些问题,特别是在使用原始SQL查询的时候。我参考了这个链接:https://docs.djangoproject.com/en/dev/topics/db/sql/。当我尝试遍历从原始SQL查询返回的RawQuerySet时,出现了错误。希望能得到一些帮助。这是我视图的一部分。
class SearchForm(forms.Form):
pr_name = forms.CharField(label="Pr Name", max_length=64, required=False)
org = forms.ModelChoiceField(queryset=Org.objects.all(), required=False)
group_name = forms.CharField(label="Unique Submission Name", max_length=64, required=False)
group_ref = forms.CharField(label="Ref", max_length=12, required=False)
group_url = forms.URLField(label="URL", required=False)
def search(request):
if request.method == 'POST':
form = SearchForm(request.POST)
if form.is_valid():
p_ids = []
g_ids = []
f_ids = []
logging.debug('hello1')
# Filter first
firstQuery = 'SELECT * FROM pr where '
pr_name = form.cleaned_data['pr_name']
if pr_name:
logging.debug('hello2')
firstQuery += '(name like \'%' + pr_name + '%\')'
else:
pass
logging.debug('hello3')
org = form.cleaned_data['org']
if org:
org = Org.objects.get(name = org)
org_id = org.id
firstQuery += '(org_id = ' + str(org_id) + ')'
else:
pass
firstQuery = firstQuery.replace(')(', ') AND (')
#logging.debug('First query: %s' % firstQuery)
p_search_results = P.objects.raw(firstQuery)
logging.debug('First query: %s' % p_search_results)
for x in p_search_results:
p_ids.append(x.id)
logging.debug('p_ids: %s' % p_ids)
# Filter Group
secondQuery = 'SELECT * FROM group where '
group_name = form.cleaned_data['group_name']
if group_name:
secondQuery += '(name like \'%' + group_name + '%\')'
else:
pass
group_ref = form.cleaned_data['group_ref']
if group_ref:
secondQuery += '(ref like \'%' + group_ref + '%\')'
else:
pass
group_url = form.cleaned_data['group_url']
if group_url:
secondQuery += '(method_url like \'%' + group_url + '%\')'
else:
pass
secondQuery = secondQuery.replace(')(', ') AND (')
logging.debug('Second query: %s' % secondQuery)
group_search_results = PredictionGroup.objects.raw(secondQuery)
logging.debug('Second query: %s' % group_search_results)
for x in group_search_results:
g_ids.append(x.id)
logging.debug('g_ids: %s' % g_ids)
...
...
...
错误信息是:
TypeError at /search/
not enough arguments for format string at:
for x in p_search_results:
2 个回答
0
这个错误 not enough arguments for format string
是因为你有一行代码像这样:
"Something %s and %s" % x
你的字符串里有两个 %s
,需要用变量来替换,但在 %
操作符后面你只提供了一个变量。
我在想,可能你的堆栈跟踪有问题,因为这个错误是因为不正确使用 %
操作符引起的。一个 for
循环是不会导致这个错误的。
2
绝对不要像那样构建SQL参数。其实这件事非常重要,我再说一遍:绝对不要像那样构建SQL参数。这样做会让你面临SQL注入攻击的风险:如果有人在你的 pr_name
字段里提交 "foo'; DELETE FROM pr;"
,会发生什么呢?没错,数据库会执行这两个命令,直接删除你的pr表。
Django通常会保护你,确保所有输入都能正确处理,避免SQL命令出错。不过,你选择绕过ORM(对象关系映射),有时候这样做是为了处理复杂的查询,但你上面展示的查询并不复杂。
你应该这样做:
group_query = Group.objects.all()
group_name = form.cleaned_data['group_name']
if group_name:
group_query = group_query.filter(name__icontains=group_name)
org = form.cleaned_data['org']
if org:
group_query = group_query.filter(org__name=org)
等等。