为什么这个 Django raw SQL 查询没有返回输出?

Why is this Django raw SQL query not returning output?

我有一个原始 SQL 查询,我正尝试在 Django 中 运行。当我显示 RawQuerySet 对象时,它显示了正确的查询,但没有返回任何输出。

我试过将参数转换为字符串并尝试在参数上附加引号,但没有用。

我也尝试过相同的查询,但我对参数进行了硬编码。成功了。

我也打开了 dbshel​​l 来尝试查看查询 returns 是否有输出。它也很好用。

这是我在我的 dbshel​​l 中 运行:

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])

我模板中的输出应该就是这个 ID 列表: 1, 64, 437, 1507, 1685

但是,现在它只是 returns []

这是两种情况下的 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')

好吧,在反复使用 shell 和调试工具栏之后,我发现了一种有点多余的方法来实现这一点。创建六个单独的字符串:

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()

此查询应为您提供用户喜欢的所有黑色商品:

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

如果您只需要原始查询中的 ID,请添加 .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)