Почему этот необработанный SQL-запрос Django не возвращает результат? - PullRequest
2 голосов
/ 26 марта 2019

У меня есть необработанный SQL-запрос, который я пытаюсь запустить в Django.Когда я отображаю объект RawQuerySet, он показывает правильный запрос, но не возвращает никакого вывода.

Я попытался преобразовать параметры в строку и попытался добавить к ним кавычки, но это не сработало.

Я также пытался выполнить тот же запрос, но я жестко закодировал параметры.Это сработало.

Я также открыл dbshell, чтобы попытаться увидеть, возвращает ли запрос вывод.Это тоже отлично работает.

Это то, что я запустил в моей dbshell:

select id FROM recommender_item WHERE 
id in (select item_id from 
recommender_item_likes where user_id = 1) 
and color = 'Black';

Обратите внимание, что следующий запрос не работал:

select id FROM recommender_item WHERE 
id in (select item_id from 
recommender_item_likes where user_id = 1) 
and color = Black;

Этофактический запрос, который я хочу выполнить:

Item.objects.raw('select id FROM recommender_item WHERE 
id in (select item_id from recommender_item_likes where 
user_id = %s) and %s = %s', [request.user.id, user_pref, pref_choice,])

Это тот же запрос с жестко заданными параметрами, который работает:

Item.objects.raw('select id FROM recommender_item WHERE 
id in (select item_id from recommender_item_likes where user_id = %s) 
and color = "Black"', [request.user.id])

Вывод в моем шаблоне должен быть именно таким списком идентификаторов.: 1, 64, 437, 1507, 1685

Однако сейчас он просто возвращает []

Это объект RawQuerySet в обоих случаях, соответственно:

<RawQuerySet: select id FROM recommender_item WHERE 
id in (select item_id from recommender_item_likes where user_id = 1) 
and color = Black>

и

<RawQuerySet: select id FROM recommender_item WHERE 
id in (select item_id from recommender_item_likes where user_id = 1) 
and color = "Black">

Фактический выполняемый SQL-запрос, полученный с панели отладки Django:

select id FROM recommender_item WHERE 
id in (select item_id from recommender_item_likes where 
user_id = '1') and '''color''' = '''"Black"'''

models.py

class Item(models.Model):
    #id = models.UUIDField(primary_key = True, default = uuid.uuid4, help_text = 'Unique ID for this particular item')
    item_type = models.CharField(max_length = 200, null = True, blank = True)
    price = models.CharField(max_length = 200, null = True, blank = True)
    color = models.CharField(max_length = 200, null = True, blank = True)
    image_URL = models.CharField(max_length = 1000, null = True, blank = True)
    fit = models.CharField(max_length = 200, null = True, blank = True)
    occasion = models.CharField(max_length = 200, null = True, blank = True)
    brand = models.CharField(max_length = 200, null = True, blank = True)
    pattern = models.CharField(max_length = 200, null = True, blank = True)
    fabric = models.CharField(max_length = 200, null = True, blank = True)
    length = models.CharField(max_length = 200, null = True, blank = True)
    likes = models.ManyToManyField(User, blank = True, related_name = 'item_likes')

Ответы [ 2 ]

1 голос
/ 27 марта 2019

Этот запрос должен получить все понравившиеся пользователю черные элементы:

Item.objects.filter(likes=request.user, color='Black')

Добавьте .values('id'), если вам нужны только идентификаторы, как в необработанном запросе.

Но я все еще нахожу вашу оригинальную проблему более интересной. У меня нет проблем с выдачей необработанных запросов со строковыми параметрами в Postgresql. Мне придется попробовать с Sqlite.

Кстати, запрос ORM подчеркивает, что likes является неправильным; likers или подобное может показаться более подходящим именем.


Вы можете расширить словарь в filter():

filter_field = 'color'
filter_string = 'black'
filter_dict = {filter_field: filter_string}
Item.objects.filter(**filter_dict)
0 голосов
/ 26 марта 2019

Хорошо, после долгих тренировок с оболочкой и панелью отладки я нашел несколько избыточный способ добиться этого.Создайте шесть отдельных строк:

str1 = 'select id FROM recommender_item WHERE id in (select item_id from recommender_item_likes where user_id ='
str2 = str(request.user.id)
str3 = ') and '
str4 = user_pref
str5 = ' = '
str6 = "'"+pref_choice+"'"
q = str1 + str2+ str3 + str4 + str5 + str6

Затем я передаю эту переменную следующим образом: Item.objects.raw(q) Это дает мне необходимый вывод.

Учитывая изменения модели, вы сможете сделать это:

Item.objects.filter(likes=request.user)

Или

request.user.item_likes.all()

...