我在Django中有一个简单的查询。我安装了Django工具栏,用于检查SQL查询和相应的数据
我的模特:
class RecipePosition(models.Model):
name = models.CharField(max_length=200,blank=True,help_text="If left blank will be same as Ingredient name Eg: Tomato pulp")
mass_quantity = models.DecimalField(max_digits=19, decimal_places=10,null=True,blank=True,default=0,validators=[MinValueValidator(0)])
title = models.CharField(max_length=200,blank=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
我有以下带有过滤器的Django查询。
RecipePosition.objects.all().filter(mass_quantity__gt = 0)
Django获取其mass_quantity大于0的所有对象。
但是当我在django-工具栏中检查sql时。它显示:
SELECT "recipes_recipeposition"."id",
"recipes_recipeposition"."name",
"recipes_recipeposition"."mass_quantity",
"recipes_recipeposition"."title",
"recipes_recipeposition"."updated",
"recipes_recipeposition"."timestamp"
FROM "recipes_recipeposition"
WHERE "recipes_recipeposition"."mass_quantity" > 'Decimal(''0'')'
ORDER BY "recipes_recipeposition"."sequence_number" ASC
我也在sqlite浏览器中尝试了此命令,但未显示任何结果。
为什么django-toolbar没有显示正确的SQL?
按照我的说法,sql应该是:
SELECT "recipes_recipeposition"."id",
"recipes_recipeposition"."name",
"recipes_recipeposition"."mass_quantity",
"recipes_recipeposition"."title",
"recipes_recipeposition"."updated",
"recipes_recipeposition"."timestamp"
FROM "recipes_recipeposition"
WHERE "recipes_recipeposition"."mass_quantity" > 0
ORDER BY "recipes_recipeposition"."sequence_number" ASC
并且在sqlite浏览器中进行测试时会显示结果。
另外,当我在shell_plus上使用--print-sql --ipython
测试时显示
$ python manage.py shell_plus --print-sql --ipython
System check identified some issues:
# Shell Plus Model Imports
from recipes.models import Recipe, RecipePosition
Python 3.6.4 (default, Jan 5 2018, 02:35:40)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: RecipePosition.objects.all().filter(mass_quantity__gt=0)
Out[1]: SELECT "recipes_recipeposition"."id",
"recipes_recipeposition"."name",
"recipes_recipeposition"."mass_quantity",
"recipes_recipeposition"."title",
"recipes_recipeposition"."updated",
"recipes_recipeposition"."timestamp"
FROM "recipes_recipeposition"
WHERE "recipes_recipeposition"."mass_quantity" > '0'
ORDER BY "recipes_recipeposition"."sequence_number" ASC
LIMIT 21
仅在django-toolbar上,它在Django shell上显示Decimal()的东西,它显示WHERE "recipes_recipeposition"."mass_quantity" > '0'
我还尝试了django-toolbar文档中提到的debugsqlshell。它显示"recipes_recipeposition"."mass_quantity" > '0'
而不是"recipes_recipeposition"."mass_quantity" > 'Decimal(''0'')'
$ python manage.py debugsqlshell
Python 3.6.4 (default, Jan 5 2018, 02:35:40)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.
In [2]: from recipes.models import Recipe, RecipePosition
In [3]: RecipePosition.objects.all().filter(mass_quantity__gt = 0)
Out[3]: SELECT "recipes_recipeposition"."id",
"recipes_recipeposition"."name",
"recipes_recipeposition"."mass_quantity",
"recipes_recipeposition"."title",
"recipes_recipeposition"."updated",
"recipes_recipeposition"."timestamp"
FROM "recipes_recipeposition"
WHERE "recipes_recipeposition"."mass_quantity" > '0'
ORDER BY "recipes_recipeposition"."sequence_number" ASC
LIMIT 21 [1.58ms]
我不知道为什么django-toobar使用"recipes_recipeposition"."mass_quantity" > 'Decimal(''0'')'
而不是"recipes_recipeposition"."mass_quantity" > '0'
我想依靠django-toolbar,但是现在我很担心。
答案 0 :(得分:0)
好消息,我认为您需要做出最大的改变!
代替:
RecipePosition.objects.all().filter(mass_quantity__gt = 0)
您需要:
RecipePosition.objects.all().filter(mass_quantity__gt=0.0)
答案 1 :(得分:0)
最后,经过许多努力并完成了代码。我在源代码中做了以下更改,然后一切都按照我想要的方式工作。
####################
http://127.0.0.1:8001/static/debug_toolbar/css/toolbar.css
# By doing this the sql will show in multiple lines with indent
#djDebug .djDebugSql {
#word-break:break-word;
z-index:100000002;
}
#####################
# replace \n with <br> and space with nbsp and dont use Boldkeyword
# By doing this the sql will show in multiple lines with indent
def reformat_sql(sql):
stack = sqlparse.engine.FilterStack()
options = formatter.validate_options({'reindent':True,'indent_width':True,})
stack = formatter.build_filter_stack(stack, options)
#stack.preprocess.append(BoldKeywordFilter()) # add our custom filter
stack.postprocess.append(sqlparse.filters.SerializerUnicode()) # tokens -> strings
#return swap_fields(''.join(stack.run(sql)))
return swap_fields(''.join(stack.run(sql)).replace("\n", "<br/>").replace(" ", " "))
#####################
in file /lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py
# because of this the greater than 0 is shown as deciman(0.0)
# change for decimal wrap p in rev_typecast_decimal
def _record(self, method, sql, params):
start_time = time()
try:
return method(sql, params)
finally:
stop_time = time()
duration = (stop_time - start_time) * 1000
if dt_settings.get_config()['ENABLE_STACKTRACES']:
stacktrace = tidy_stacktrace(reversed(get_stack()))
else:
stacktrace = []
_params = ''
try:
_params = json.dumps([self._decode(rev_typecast_decimal(p)) for p in params])
#_params = json.dumps([self._decode(p) for p in params]) I
###########################
hare = []
if params is not None:
hare = [self._decode(rev_typecast_decimal(p)) for p in params]
try:
_params = json.dumps([self._decode(rev_typecast_decimal(p)) for p in params])
# _params = json.dumps([self._decode(p) for p in params])
except Exception:
pass # object not JSON serializable
template_info = get_template_info()
alias = getattr(self.db, 'alias', 'default')
conn = self.db.connection
vendor = getattr(conn, 'vendor', 'unknown')
params1 = {
'vendor': vendor,
'alias': alias,
# 'sql': self.db.ops.last_executed_query(
# self.cursor, sql, self._quote_params(params)),
'sql': self.db.ops.last_executed_query(
self.cursor, sql, hare),
'duration': duration,
'raw_sql': sql,
'params': _params,
'stacktrace': stacktrace,
'start_time': start_time,
'stop_time': stop_time,
'is_slow': duration > dt_settings.get_config()['SQL_WARNING_THRESHOLD'],
'is_select': sql.lower().strip().startswith('select'),
'template_info': template_info,
}
################################################
最终输出看起来像,用小数(0.0)替换为0且格式正确的sql
SELECT "recipes_recipeposition"."id",
"recipes_recipeposition"."name",
"recipes_recipeposition"."recipe_id",
"recipes_recipeposition"."ingredient_id",
"recipes_recipeposition"."recipeposition_slug",
"recipes_recipeposition"."cooking_unit",
"recipes_recipeposition"."mass_unit_id",
"recipes_recipeposition"."mass_quantity",
"recipes_recipeposition"."volume_unit_id",
"recipes_recipeposition"."volume_quantity",
"recipes_recipeposition"."pieces_unit_id",
"recipes_recipeposition"."pieces_quantity",
"recipes_recipeposition"."cooking_notes",
"recipes_recipeposition"."sequence_number",
"recipes_recipeposition"."title",
"recipes_recipeposition"."updated",
"recipes_recipeposition"."timestamp",
"ingredients_ingredient"."rate" AS "ingredient__rate",
CASE
WHEN "ingredients_ingredient"."munit" = 'kg' THEN 'kg'
WHEN "ingredients_ingredient"."munit" = 'ltr' THEN 'ltr'
WHEN "ingredients_ingredient"."munit" = 'pcs' THEN 'pcs'
ELSE 'False'
END AS "ingredient__cost_unit",
CASE
WHEN "ingredients_ingredient"."munit" = 'kg' THEN CASE
WHEN ("recipes_recipeposition"."mass_unit_id" IS NOT NULL
AND "recipes_recipeposition"."mass_quantity" IS NOT NULL
AND "recipes_recipeposition"."mass_quantity" > '0') THEN CAST(("recipes_recipeposition"."mass_quantity" * "single_measurements_singlemeasurements"."quantity") AS NUMERIC)
ELSE 'False'
END
WHEN "ingredients_ingredient"."munit" = 'ltr' THEN 'ltr'
WHEN "ingredients_ingredient"."munit" = 'pcs' THEN 'pcs'
ELSE 'False'
END AS "reciposition_cost_quantity"
FROM "recipes_recipeposition"
LEFT OUTER JOIN "ingredients_ingredient" ON ("recipes_recipeposition"."ingredient_id" = "ingredients_ingredient"."id")
LEFT OUTER JOIN "single_measurements_singlemeasurements" ON ("recipes_recipeposition"."mass_unit_id" = "single_measurements_singlemeasurements"."id")
WHERE "recipes_recipeposition"."recipe_id" = '1'
ORDER BY "recipes_recipeposition"."sequence_number" ASC