Python Django 原始 sql 迭代导致 TypeError

发布于 2024-12-10 19:43:04 字数 2890 浏览 0 评论 0原文

使用原始 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一直在等你来 2024-12-17 19:43:04

永远、永远、永远、永远、永远不要像这样建立 SQL 参数。事实上,这非常重要,我要再说一遍:永远、永远、永远、永远、永远、永远,建立这样的 SQL 参数。您已经让自己面临 SQL 注入攻击:如果有人将 "foo'; DELETE FROM pr;" 提交到您的 pr_name 字段,会发生什么情况?没错,数据库会忠实执行两条命令,删除你的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)

等等。

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 your pr_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:

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)

and so on.

孤芳又自赏 2024-12-17 19:43:04

错误格式字符串的参数不足来自这样的一行:

"Something %s and %s" % x

您的字符串有两个需要替换的%s,但是后面只有一个变量代码>% 运算符。

我不禁想知道您的堆栈跟踪是否有问题,因为该错误来自于错误地使用 % 运算符。 for 循环不会触发它。

The error not enough arguments for format string comes from a line like this:

"Something %s and %s" % x

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. A for loop wouldn't trigger that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文