django查詢中extra的應用

2021-09-14 07:17:09 字數 3803 閱讀 4153

今天有個需求需要查詢到資料庫resc_metadata欄位(是乙個json型別的值)中job_group去重後的值放入乙個列表

一、通過pymysql完成

def

set_cluster_id_value

(data, hirer, resc_dict)

: db = mysqldb.connect(sqlconf[

"ipaddr"

], sqlconf[

"username"

], sqlconf[

"passwd"

], sqlconf[

"table"

], charset=sqlconf[

"charset"

], port=sqlconf[

"port"])

# 使用cursor()方法獲取操作游標

cursor = db.cursor(

) query_sql =

"""select

distinct(resc_metadata->'$.job_group')

where resource_type = 'job' and bettle_id != -1000 and hirer='%s' """

%(hirer)

# 使用execute方法執行sql語句

cursor.execute(query_sql)

job_groups = cursor.fetchall(

) exist_flag =

false

for job_group in job_groups:

# data['job_group']返回的資料樣式是:'"abc"'

if'"%s"'

%data[

'job_group'

]in job_group:

exist_flag =

true

break

if exist_flag:

pass

else

:pass

return resc_dict

二、通過extra 獲取
def

set_cluster_id_value

(data, hirer, resc_metadata)

:if resc_metadata[

'cluster_id']==

'':return resc_metadata

# sql語句的!=在這裡只能用 ~q 代替

job_groups = rescdetail.objects.using(rescdetailconf.db)

.filter

(q(resource_type=

'job')&

~q(bettle_id=

-1000

)& q(hirer=hirer)

).extra(

select=

).values(

'job_group'

).distinct(

) exist_flag =

false

for job_group in job_groups:

if'"%s"'

% data[

'job_group'

]== job_group[

'job_group']:

exist_flag =

true

break

if exist_flag:

pass

else

:pass

return resc_metadata

如果查詢的值不是json型別,直接使用distinct()就可以了。

rescdetail.objects.using(rescdetailconf.db)

.filter

(q(resource_type=

'job')&

~q(bettle_id=

-1000

)& q(hirer=hirer)

).values(

'job_group'

).distinct(

)

extra的介紹
extra(select=none, where=none, params=none, tables=none, order_by=none, select_params=none)
有些情況下,django的查詢語法難以簡單的表達複雜的 where 子句,對於這種情況, django 提供了 extra() queryset修改機制 — 它能在 queryset生成的sql從句中注入新子句。

extra可以指定乙個或多個 引數,例如 select, where or tables. 這些引數都不是必須的,但是你至少要使用乙個!要注意這些額外的方式對不同的資料庫引擎可能存在移植性問題.(因為你在顯式的書寫sql語句),除非萬不得已,盡量避免這樣做.

引數之select

the select 引數可以讓你在 select 從句中新增其他字段資訊,它應該是乙個字典,存放著屬性名到 sql 從句的對映。

queryresult=article.objects.extra(select=)
結果集中每個 entry 物件都有乙個額外的屬性is_recent, 它是乙個布林值,表示 article物件的create_time 是否晚於2018-04-18. 

練習:

# in sqlite:

article_obj=models.article.objects.

filter

(nid=1)

.extra(select=

).values(

"standard_time"

,"nid"

,"title"

)print

(article_obj)

#

引數之where /tables:

您可以使用where定義顯式sql where子句 - 也許執行非顯式連線。您可以使用tables手動將表新增到sql from子句。

where和tables都接受字串列表。所有where引數均為「與」任何其他搜尋條件。

練習:

queryresult=models.article

.objects.extra(where=

['nid in (1,3) or title like "py%" '

,'nid>2'

])

例子:
## select提供簡單資料

person.objects.all().extra(select=) # 加在select後面

## where提供查詢條件

person.objects.all().extra(where=["first||last ilike 'jeffrey%'"]) # 加乙個where條件

## table連線其它表

## params添引數

# !! 錯誤的方式 !!

first_name = 'joe' # 如果first_name中有sql特定字元就會出現漏洞

person.objects.all().extra(where=["first = '%s'" % first_name])

# 正確方式

person.objects.all().extra(where=["first = '%s'"], params=[first_name])

django模型方法extra

select提供簡單資料 person.objects.all extra select 加在select後面 where提供查詢條件 person.objects.all extra where first last ilike jeffrey 加乙個where條件 table連線其它表 book...

django查詢中的 in

rackid request.post rackid retdir rackid rackid racks rack.objects.filter rackid icontains rackid equipments equipment.objects.filter rack in racks 可以...

Django中的連線查詢

django中的連線查詢 建立一對一對映語法 class wife models.model name models.charfield max length 30,verbose name 姓名 age models.integerfield verbose name 年齡 增加一對一的關係對映,...