为什么此Django原始SQL查询未返回输出?

时间:2019-03-26 14:56:36

标签: sql django sqlite django-models django-orm

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

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

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

我也打开了dbshel​​l,尝试查看查询是否返回输出。也可以。

这是我在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

但是,现在它只返回[]

在两种情况下,这都是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 个答案:

答案 0 :(得分:1)

此查询应使您获得用户喜欢的所有黑色物品:

< application
android:name=".ExampleApplication"
android:networkSecurityConfig="@xml/network_security_config"
android:allowBackup="false"
tools:replace="android:allowBackup"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">

如果只需要原始查询中的ID,请添加Item.objects.filter(likes=request.user, color='Black')

但是我仍然觉得您原来的问题更有趣。我将带有字符串参数的原始查询发布给Postgresql没有问题。我必须尝试使用​​Sqlite。

顺便说一句,ORM查询突出显示.values('id')是用词不当; likes或类似名称似乎更合适。


您可以在likers中展开字典:

filter()

答案 1 :(得分:0)

好吧,在使用了很多外壳程序和调试工具栏之后,我发现了一种实现此目的的多余方法。创建六个单独的字符串:

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