Python Django 原始 sql 迭代导致 TypeError
使用原始 sql 查询时,我在 python django 中处理表单时遇到一些问题。我使用 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:
I am having some problems with processing my form in python django when using raw sql querying. I used https://docs.djangoproject.com/en/dev/topics/db/sql/ for reference. I am getting errors when trying to iterate over the RawQuerySet that is returned from the raw sql query. Any help would be appreciated. Here is part of my view.
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)
...
...
...
And the error is:
TypeError at /search/
not enough arguments for format string at:
for x in p_search_results:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
永远、永远、永远、永远、永远不要像这样建立 SQL 参数。事实上,这非常重要,我要再说一遍:永远、永远、永远、永远、永远、永远,建立这样的 SQL 参数。您已经让自己面临 SQL 注入攻击:如果有人将
"foo'; DELETE FROM pr;"
提交到您的pr_name
字段,会发生什么情况?没错,数据库会忠实执行两条命令,删除你的pr表。Django 通常会通过正确转义 SQL 命令的所有输入来保护您免受这种情况的影响。由于某种原因,您选择绕过 ORM:现在,有时您需要这样做,以便制定复杂的查询,但上面显示的查询中没有任何复杂的内容。
你应该做这样的事情:
等等。
Never, ever, ever, ever, ever build up SQL parameters like that. In fact, that's so important, I'm going to say it again: never, ever, ever, ever, ever, ever, build up SQL parameters like that. You've left yourself wide open to an SQL injection attack: what happens if someone submits
"foo'; DELETE FROM pr;"
into yourpr_name
field? That's right, the database will faithfully execute two commands and delete your pr table.Django normally protects you from that, by properly escaping all input to SQL commands. For some reason, you've chosen to bypass the ORM: now, sometimes you need to, in order to formulate complex queries, but there's nothing complex in the queries you show above.
You should be doing something like this:
and so on.
错误
格式字符串的参数不足
来自这样的一行:您的字符串有两个需要替换的
%s
,但是后面只有一个变量代码>%
运算符。我不禁想知道您的堆栈跟踪是否有问题,因为该错误来自于错误地使用
%
运算符。for
循环不会触发它。The error
not enough arguments for format string
comes from a line like this:Your string has two
%s
which need to be substituted, but you only have one variable after the%
operator.I can't help wonder if something's wrong with your stack trace, because that error comes from using the
%
operator incorrectly. Afor
loop wouldn't trigger that.