【问题标题】:Python Django raw sql iteration leads to TypeErrorPython Django raw sql迭代导致TypeError
【发布时间】:2011-12-11 03:41:11
【问题描述】:

在使用原始 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:

【问题讨论】:

    标签: python sql django django-models django-views


    【解决方案1】:

    错误not enough arguments for format string来自如下一行:

    "Something %s and %s" % x
    

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

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

    【讨论】:

      【解决方案2】:

      从来没有,从来没有,从来没有,曾经建立过这样的 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)
      

      等等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-27
        • 2020-02-28
        • 2019-07-25
        • 1970-01-01
        • 2021-06-09
        • 1970-01-01
        • 2012-04-27
        • 1970-01-01
        相关资源
        最近更新 更多