django使用raw()执行sql语句多表查询

1.环境

python3.7

django2.2.16

mysql5.7

2.raw()的用法

  • raw() 执行原始sql,并返回模型实例对象。

  • 可用于多表关联查询

  • 返回结果必须包含实例对象对应数据库表的主键

  • 虽然返回结果是实例对象,但是对于多表关联查询,返回结果可以包含非实例对象(关联查询表)的字段属性。

  • 如果最终查询结果中有的字段不存在于任何实例对象或关联查询对象中则会报错[Cannot resolve keyword ‘XXX’ into field. Choices are: app_label, id, model…],即最终查询的字段必须在关联查询的表中,不能凭空捏造。

3.实例

数据库表:product(产品表) model_replace(产品型号替换表),两个表并没有外键关联关系,只是通过一个product_unique_sign去关联

product

product_id product_name product_model product_unique_sign
1 产品1 model01 1001
2 产品2 model02 1002
3 产品3 model03 1003

model_replace

model_id product_model product_model_replace product_unique_sign
1 model02 model01 1002
2 model02 model03 1002
def search(request):	
	params = ""
	# 根据自己的业务逻辑可以在params添加where的查询条件,拼接到sql_str字符串中
	# 如果是字符串类型的参数,记得在{}的两侧加上单引号,否则会报错。
	# 因为生成的sql语句 会是  and p.product_model = model02 。这种SQL语句肯定是错误的。
	param_model = "model02"
	params += " and p.product_model = '{}' ".format(param_model)
	sql_str = "select p.product_id as product_id, p.product_name as product_name,p.product_model as product_model,p.product_unique_sign as product_unique_sign,m.product_model_replace as product_model_replace from product as p left join model_replace on p.product_unique_sign = m.product_unique_sign where 1=1 {}".format(params)
	models2 = Product.objects.raw(str_sql)
	data2 = []
	if models2 and len(models2) > 0:
	    for temp in models2:
	        data2.append(change_obj_to_dict(temp))
	# *****最终获得data2是一个字典的集合
	print("data2={}".format(data2))
	
	# 分页后的每页总数据
	data_page = Paginator(data2, row_count)
	# 总页数
	page_total = data_page.num_pages
	# 获取当前页面的数据列表
	data = data_page.page(page_current).object_list
	# 总共多少条数据
	row_num = data_page.count
	
	dict_data = {
     "data": data, "row_num": row_num, "row_count": 			  row_count, "page_total": page_total, "page_current": page_current, }
	dict_data = json.dumps(dict_data)
	# print(dict_data)
	# 返回前台数据
	return HttpResponse(dict_data)
# 对应sqla_str中的查询条件的字段
def change_obj_to_dict(temp):
    dict = {
     }
    dict["product_id"] = temp.product_id
    dict["product_name"] = temp.product_name
    dict["product_model"] = temp.product_model
    dict["product_unique_sign"] = temp.product_unique_sign
    # 虽然产品表里没有替代型号,但是通过sql语句的raw()查询可以查到结果中是包含非实例对象的字段的
    dict["product_model_replace"] = temp.product_model_replace
    
    return dict

你可能感兴趣的:(Django,Python,python,django,mysql)