Python Django raw sql итерация приводит к TypeError - PullRequest
0 голосов
/ 19 октября 2011

У меня возникли проблемы с обработкой формы в Python django при использовании необработанных запросов SQL Я использовал https://docs.djangoproject.com/en/dev/topics/db/sql/ для справки. Я получаю ошибки при попытке перебрать RawQuerySet, который возвращается из необработанного SQL-запроса. Любая помощь будет оценена. Вот часть моего взгляда.

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 ]

2 голосов
/ 19 октября 2011

Никогда, никогда, никогда, никогда не создавайте такие параметры 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)

и т. Д.

0 голосов
/ 19 октября 2011

Ошибка not enough arguments for format string исходит из такой строки:

"Something %s and %s" % x

В вашей строке два %s, которые необходимо заменить, но у вас есть только одна переменная после оператора %.

Я не могу не задаться вопросом, что-то не так с вашей трассировкой стека, потому что эта ошибка происходит из-за неправильного использования оператора %. Цикл for не вызовет этого.

...