extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
extra(select=None, where=None, params=None,
tables=None, order_by=None, select_params=None)
有些狀況下,Django的查詢語法難以簡單的表達複雜的 WHERE 子句,對於這種狀況, Django 提供了 extra() QuerySet修改機制 — 它能在 QuerySet生成的SQL從句中注入新子句java
extra能夠指定一個或多個 參數,例如 select, where or tables. 這些參數都不是必須的,可是你至少要使用一個!要注意這些額外的方式對不一樣的數據庫引擎可能存在移植性問題.(由於你在顯式的書寫SQL語句),除非萬不得已,儘可能避免這樣作python
警告web
不管什麼時候你都須要很是當心的使用extra(). 每次使用它時,您都應該轉義用戶可使用params控制的任何參數,以防止SQL注入攻擊。sql
queryResult=models.Article .objects.extra(select={'is_recent': "create_time > '2017-09-05'"})
queryResult=models.Article
.objects.extra(select={'is_recent': "create_time > '2017-09-05'"})
date_list=models.Article.objects.filter(user=user_obj).extra(select={"fdate":"strftime('%%Y/%%m/%%d',create_time)"}).values_list("fdate").annotate(Count("id")) ''' 輸出結果: <QuerySet [('2017/11/22', 2), ('2017/11/24', 1)]> '''
date_list=models.Article.objects.filter(user=user_obj).extra(select={"fdate":"strftime('%%Y/%%m/%%d',create_time)"}).values_list("fdate").annotate(Count("id"))
'''
輸出結果:
<QuerySet [('2017/11/22', 2), ('2017/11/24', 1)]>
'''
您可使用where定義顯式SQL WHERE子句 - 也許執行非顯式鏈接。您可使用tables手動將表添加到SQL FROM子句。數據庫
where和tables都接受字符串列表。全部where參數均爲「與」任何其餘搜索條件。bootstrap
舉例來說:api
queryResult=models.Article .objects.extra(where=['nid in (1,3) OR title like "py%" ','nid>2'])
queryResult=models.Article
.objects.extra(where=['nid in (1,3) OR title like "py%" ','nid>2'])
>>> Entry.objects.all()[:5] # (LIMIT 5)
>>> Entry.objects.all()[:5] # (LIMIT 5)
articleList=models.Article.objects.all() for article in articleList: print(article.title)
articleList=models.Article.objects.all()
for article in articleList:
print(article.title)
def queryTest(request): ret=models.Article.objects.all().iterator() for i in ret: print(i) return HttpResponse("ok") 輸出結果: #打印了就進行查詢 ''' Quit the server with CTRL-BREAK. (0.001) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_a rticle"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id" FROM "app01_article"; args=() bootstrap導航欄.nav與.navbar區別 [Python]循環嵌套nested loop-練習題 Java提升十五:容器元素比較Comparable&Comparator深刻分析 dsds sql dsdsds dsds 東京不太熱 dsds 東京有點熱 射太陽的人 '''
def queryTest(request):
ret=models.Article.objects.all().iterator()
for i in ret:
print(i)
return HttpResponse("ok")
輸出結果:
#打印了就進行查詢
'''
Quit the server with CTRL-BREAK.
(0.001) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_a
rticle"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id" FROM "app01_article"; args=()
bootstrap導航欄.nav與.navbar區別
[Python]循環嵌套nested loop-練習題
Java提升十五:容器元素比較Comparable&Comparator深刻分析
dsds
sql
dsdsds
dsds
東京不太熱
dsds
東京有點熱
射太陽的人
'''
def queryTest(request): ret=models.Article.objects.all().iterator() # for i in ret: # print(i) return HttpResponse("ok") 輸出結果: #不打印則不進行查詢
def queryTest(request):
ret=models.Article.objects.all().iterator()
# for i in ret:
# print(i)
return HttpResponse("ok")
輸出結果:
#不打印則不進行查詢
def queryTest(request): ret=models.Article.objects.all() #將qureyset放入一個變量 for i in ret: #而後兩次循環這個變量 print(i) for i in ret: print(i) return HttpResponse("ok") 輸出結果: #只查詢了一次,可是打印了兩次,說明第一次查詢的值已經緩存到了變量中,下次直接從緩存中拿值就能夠了 ''' (0.001) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_ article"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id" FROM "app01_article"; args=() bootstrap導航欄.nav與.navbar區別 [Python]循環嵌套nested loop-練習題 Java提升十五:容器元素比較Comparable&Comparator深刻分析 dsds sql dsdsds dsds 東京不太熱 dsds 東京有點熱 射太陽的人 bootstrap導航欄.nav與.navbar區別 [Python]循環嵌套nested loop-練習題 Java提升十五:容器元素比較Comparable&Comparator深刻分析 dsds sql dsdsds dsds 東京不太熱 dsds 東京有點熱 射太陽的人 '''
x
def queryTest(request):
ret=models.Article.objects.all() #將qureyset放入一個變量
for i in ret: #而後兩次循環這個變量
print(i)
for i in ret:
print(i)
return HttpResponse("ok")
輸出結果:
#只查詢了一次,可是打印了兩次,說明第一次查詢的值已經緩存到了變量中,下次直接從緩存中拿值就能夠了
'''
(0.001) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_
article"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id" FROM "app01_article"; args=()
bootstrap導航欄.nav與.navbar區別
[Python]循環嵌套nested loop-練習題
Java提升十五:容器元素比較Comparable&Comparator深刻分析
dsds
sql
dsdsds
dsds
東京不太熱
dsds
東京有點熱
射太陽的人
bootstrap導航欄.nav與.navbar區別
[Python]循環嵌套nested loop-練習題
Java提升十五:容器元素比較Comparable&Comparator深刻分析
dsds
sql
dsdsds
dsds
東京不太熱
dsds
東京有點熱
射太陽的人
'''
簡單的使用if語句進行判斷也會徹底執行整個queryset而且把數據放入cache,雖然你並不須要這些 數據!爲了不這個,能夠用exists()方法來檢查是否有數據:緩存
if queryResult.exists(): #SELECT (1) AS "a" FROM "blog_article" LIMIT 1; args=() print("exists...")
if queryResult.exists():
#SELECT (1) AS "a" FROM "blog_article" LIMIT 1; args=()
print("exists...")
當queryset很是巨大時,cache會成爲問題。app
處理成千上萬的記錄時,將它們一次裝入內存是很浪費的。更糟糕的是,巨大的queryset可能會鎖住系統 進程,讓你的程序瀕臨崩潰。要避免在遍歷數據的同時產生queryset cache,可使用iterator()方法 來獲取數據,處理完數據就將其丟棄。ide
def queryTest(request): ret=models.Article.objects.all().iterator() #優化查詢後面添加iterator(),至關因而一個迭代器 #iterator()能夠一次只從數據庫獲取少許數據,這樣能夠節省內存 for i in ret: print(i) for i in ret: print(i) #第二次無結果 return HttpResponse("ok") 輸出結果: #優化查詢就是迭代器第一次查詢遍歷到最後了,後面在打印一次就取得是空值 ''' (0.001) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_ article"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id" FROM "app01_article"; args=() bootstrap導航欄.nav與.navbar區別 [Python]循環嵌套nested loop-練習題 Java提升十五:容器元素比較Comparable&Comparator深刻分析 dsds sql dsdsds dsds 東京不太熱 dsds 東京有點熱 射太陽的人 '''
x
def queryTest(request):
ret=models.Article.objects.all().iterator() #優化查詢後面添加iterator(),至關因而一個迭代器
#iterator()能夠一次只從數據庫獲取少許數據,這樣能夠節省內存
for i in ret:
print(i)
for i in ret:
print(i) #第二次無結果
return HttpResponse("ok")
輸出結果:
#優化查詢就是迭代器第一次查詢遍歷到最後了,後面在打印一次就取得是空值
'''
(0.001) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_
article"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id" FROM "app01_article"; args=()
bootstrap導航欄.nav與.navbar區別
[Python]循環嵌套nested loop-練習題
Java提升十五:容器元素比較Comparable&Comparator深刻分析
dsds
sql
dsdsds
dsds
東京不太熱
dsds
東京有點熱
射太陽的人
'''
處理相似搭配 pizza 和 topping 這樣簡單的多對多關係時,使用標準的ManyToManyField 就能夠了。可是,有時你可能須要關聯數據到兩個模型之間的關係上。
例如,有這樣一個應用,它記錄音樂家所屬的音樂小組。咱們能夠用一個ManyToManyField 表示小組和成員之間的多對多關係。可是,有時你可能想知道更多成員關係的細節,好比成員是什麼時候加入小組的。
對於這些狀況,Django 容許你指定一箇中介模型來定義多對多關係。 你能夠將其餘字段放在中介模型裏面。源模型的ManyToManyField 字段將使用through 參數指向中介模型。對於官網上的的音樂小組的例子,我寫的blog系統的關係的代碼以下:
class Article(models.Model): ''' 文章表 ''' title = models.CharField(max_length=50, verbose_name='文章標題') desc = models.CharField(max_length=255, verbose_name='文章描述') read_count = models.IntegerField(default=0) comment_count = models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0) create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) category = models.ForeignKey(verbose_name='文章類型', to='Category', null=True,blank=True) user = models.ForeignKey(verbose_name='所屬用戶', to='Userinfo') tags = models.ManyToManyField( to="Tag", through='Article2Tag', #自定義建立多對多的表 through_fields=('article', 'tag'), ) site_article_category = models.ForeignKey("SiteArticleCategory", null=True) def __str__(self): return self.title class Mate: verbose_name_plural = "文章表" class Tag(models.Model): title = models.CharField(verbose_name='標籤名稱', max_length=32) blog = models.ForeignKey(verbose_name='所屬博客', to='Blog') class Mate: verbose_name_plural = "標籤表" def __str__(self): return self.title class Article2Tag(models.Model): article = models.ForeignKey(verbose_name='文章', to="Article") tag = models.ForeignKey(verbose_name='標籤', to="Tag") class Meta: unique_together = [ #惟一 ('article', 'tag'), ] def __str__(self): return self.tag
x
class Article(models.Model):
'''
文章表
'''
title = models.CharField(max_length=50, verbose_name='文章標題')
desc = models.CharField(max_length=255, verbose_name='文章描述')
read_count = models.IntegerField(default=0)
comment_count = models.IntegerField(default=0)
up_count = models.IntegerField(default=0)
down_count = models.IntegerField(default=0)
create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)
category = models.ForeignKey(verbose_name='文章類型', to='Category', null=True,blank=True)
user = models.ForeignKey(verbose_name='所屬用戶', to='Userinfo')
tags = models.ManyToManyField(
to="Tag",
through='Article2Tag', #自定義建立多對多的表
through_fields=('article', 'tag'),
)
site_article_category = models.ForeignKey("SiteArticleCategory", null=True)
def __str__(self):
return self.title
class Mate:
verbose_name_plural = "文章表"
class Tag(models.Model):
title = models.CharField(verbose_name='標籤名稱', max_length=32)
blog = models.ForeignKey(verbose_name='所屬博客', to='Blog')
class Mate:
verbose_name_plural = "標籤表"
def __str__(self):
return self.title
class Article2Tag(models.Model):
article = models.ForeignKey(verbose_name='文章', to="Article")
tag = models.ForeignKey(verbose_name='標籤', to="Tag")
class Meta:
unique_together = [ #惟一
('article', 'tag'),
]
def __str__(self):
return self.tag
文章表 |
標籤表 | 文章跟標籤的相關聯的表 | **還能夠添加別的字段 | ||||||
id | id | article_id | tag_id | 標籤分類 | 。。 | ||||
爲何不能這樣作? 這是由於你不能只建立 Person和 Group之間的關聯關係,你還要指定 Membership模型中所須要的全部信息;而簡單的add、create 和賦值語句是作不到這一點的。因此它們不能在使用中介模型的多對多關係中使用。此時,惟一的辦法就是建立中介模型的實例。
remove()方法被禁用也是出於一樣的緣由。可是clear() 方法倒是可用的。它能夠清空某個實例全部的多對多關係:
只能經過添加表記錄的方式來進行添加了
示例:
models.Article2Tag.objects.create(article_id=1,tag_id=1,) #後面添加自定義字段的值就行了
x
models.Article2Tag.objects.create(article_id=1,tag_id=1,) #後面添加自定義字段的值就行了
class UserInfo(AbstractUser): """ 用戶信息 """ nid = models.BigAutoField(primary_key=True) nickname = models.CharField(verbose_name='暱稱', max_length=32) telephone = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手機號碼') avatar = models.FileField(verbose_name='頭像',upload_to = 'avatar/',default="/avatar/default.png") create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) fans = models.ManyToManyField(verbose_name='粉絲們', to='UserInfo', through='UserFans', related_name='f', through_fields=('user', 'follower')) def __str__(self): return self.username class UserFans(models.Model): """ 互粉關係表 """ nid = models.AutoField(primary_key=True) user = models.ForeignKey(verbose_name='博主', to='UserInfo', to_field='nid', related_name='users') follower = models.ForeignKey(verbose_name='粉絲', to='UserInfo', to_field='nid', related_name='followers') class Blog(models.Model): """ 博客信息 """ nid = models.BigAutoField(primary_key=True) title = models.CharField(verbose_name='我的博客標題', max_length=64) site = models.CharField(verbose_name='我的博客後綴', max_length=32, unique=True) theme = models.CharField(verbose_name='博客主題', max_length=32) user = models.OneToOneField(to='UserInfo', to_field='nid') def __str__(self): return self.title class Category(models.Model): """ 博主我的文章分類表 """ nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='分類標題', max_length=32) blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid') class Article(models.Model): nid = models.BigAutoField(primary_key=True) title = models.CharField(max_length=50, verbose_name='文章標題') desc = models.CharField(max_length=255, verbose_name='文章描述') read_count = models.IntegerField(default=0) comment_count= models.IntegerField(default=0) up_count = models.IntegerField(default=0) down_count = models.IntegerField(default=0) category = models.ForeignKey(verbose_name='文章類型', to='Category', to_field='nid', null=True) create_time = models.DateField(verbose_name='建立時間') blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid') tags = models.ManyToManyField( to="Tag", through='Article2Tag', through_fields=('article', 'tag'), ) class ArticleDetail(models.Model): """ 文章詳細表 """ nid = models.AutoField(primary_key=True) content = models.TextField(verbose_name='文章內容', ) article = models.OneToOneField(verbose_name='所屬文章', to='Article', to_field='nid') class Comment(models.Model): """ 評論表 """ nid = models.BigAutoField(primary_key=True) article = models.ForeignKey(verbose_name='評論文章', to='Article', to_field='nid') content = models.CharField(verbose_name='評論內容', max_length=255) create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True) parent_comment = models.ForeignKey('self', blank=True, null=True, verbose_name='父級評論') user = models.ForeignKey(verbose_name='評論者', to='UserInfo', to_field='nid') up_count = models.IntegerField(default=0) def __str__(self): return self.content class ArticleUpDown(models.Model): """ 點贊表 """ nid = models.AutoField(primary_key=True) user = models.ForeignKey('UserInfo', null=True) article = models.ForeignKey("Article", null=True) models.BooleanField(verbose_name='是否贊') class CommentUp(models.Model): """ 點贊表 """ nid = models.AutoField(primary_key=True) user = models.ForeignKey('UserInfo', null=True) comment = models.ForeignKey("Comment", null=True) class Tag(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(verbose_name='標籤名稱', max_length=32) blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid') class Article2Tag(models.Model): nid = models.AutoField(primary_key=True) article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid') tag = models.ForeignKey(verbose_name='標籤', to="Tag", to_field='nid')
class UserInfo(AbstractUser):
"""
用戶信息
"""
nid = models.BigAutoField(primary_key=True)
nickname = models.CharField(verbose_name='暱稱', max_length=32)
telephone = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手機號碼')
avatar = models.FileField(verbose_name='頭像',upload_to = 'avatar/',default="/avatar/default.png")
create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)
fans = models.ManyToManyField(verbose_name='粉絲們',
to='UserInfo',
through='UserFans',
related_name='f',
through_fields=('user', 'follower'))
def __str__(self):
return self.username
class UserFans(models.Model):
"""
互粉關係表
"""
nid = models.AutoField(primary_key=True)
user = models.ForeignKey(verbose_name='博主', to='UserInfo', to_field='nid', related_name='users')
follower = models.ForeignKey(verbose_name='粉絲', to='UserInfo', to_field='nid', related_name='followers')
class Blog(models.Model):
"""
博客信息
"""
nid = models.BigAutoField(primary_key=True)
title = models.CharField(verbose_name='我的博客標題', max_length=64)
site = models.CharField(verbose_name='我的博客後綴', max_length=32, unique=True)
theme = models.CharField(verbose_name='博客主題', max_length=32)
user = models.OneToOneField(to='UserInfo', to_field='nid')
def __str__(self):
return self.title
class Category(models.Model):
"""
博主我的文章分類表
"""
nid = models.AutoField(primary_key=True)
title = models.CharField(verbose_name='分類標題', max_length=32)
blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid')
class Article(models.Model):
nid = models.BigAutoField(primary_key=True)
title = models.CharField(max_length=50, verbose_name='文章標題')
desc = models.CharField(max_length=255, verbose_name='文章描述')
read_count = models.IntegerField(default=0)
comment_count= models.IntegerField(default=0)
up_count = models.IntegerField(default=0)
down_count = models.IntegerField(default=0)
category = models.ForeignKey(verbose_name='文章類型', to='Category', to_field='nid', null=True)
create_time = models.DateField(verbose_name='建立時間')
blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid')
tags = models.ManyToManyField(
to="Tag",
through='Article2Tag',
through_fields=('article', 'tag'),
)
class ArticleDetail(models.Model):
"""
文章詳細表
"""
nid = models.AutoField(primary_key=True)
content = models.TextField(verbose_name='文章內容', )
article = models.OneToOneField(verbose_name='所屬文章', to='Article', to_field='nid')
class Comment(models.Model):
"""
評論表
"""
nid = models.BigAutoField(primary_key=True)
article = models.ForeignKey(verbose_name='評論文章', to='Article', to_field='nid')
content = models.CharField(verbose_name='評論內容', max_length=255)
create_time = models.DateTimeField(verbose_name='建立時間', auto_now_add=True)
parent_comment = models.ForeignKey('self', blank=True, null=True, verbose_name='父級評論')
user = models.ForeignKey(verbose_name='評論者', to='UserInfo', to_field='nid')
up_count = models.IntegerField(default=0)
def __str__(self):
return self.content
class ArticleUpDown(models.Model):
"""
點贊表
"""
nid = models.AutoField(primary_key=True)
user = models.ForeignKey('UserInfo', null=True)
article = models.ForeignKey("Article", null=True)
models.BooleanField(verbose_name='是否贊')
class CommentUp(models.Model):
"""
點贊表
"""
nid = models.AutoField(primary_key=True)
user = models.ForeignKey('UserInfo', null=True)
comment = models.ForeignKey("Comment", null=True)
class Tag(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(verbose_name='標籤名稱', max_length=32)
blog = models.ForeignKey(verbose_name='所屬博客', to='Blog', to_field='nid')
class Article2Tag(models.Model):
nid = models.AutoField(primary_key=True)
article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid')
tag = models.ForeignKey(verbose_name='標籤', to="Tag", to_field='nid')
對於一對一字段(OneToOneField)和外鍵字段(ForeignKey),可使用select_related 來對QuerySet進行優化。
select_related 返回一個QuerySet,當執行它的查詢時它沿着外鍵關係查詢關聯的對象的數據。它會生成一個複雜的查詢並引發性能的損耗,可是在之後使用外鍵關係時將不須要數據庫查詢。
簡單說,在對QuerySet使用select_related()函數後,Django會獲取相應外鍵對應的對象,從而在以後須要的時候沒必要再查詢數據庫了。
下面的例子解釋了普通查詢和select_related() 查詢的區別。
普通查詢
(0.000) SELECT "app01_category"."id", "app01_category"."title", "app01_category"."blog_id" FROM "app01_category" WHERE "app01_category"."id" = 2; args=(2,) yang的python
x
(0.000) SELECT "app01_category"."id", "app01_category"."title", "app01_category"."blog_id" FROM "app01_category" WHERE "app01_category"."id" = 2; args=(2,)
yang的python
articleList = models.Article.objects.select_related("category").all() for article_obj in articleList: # Doesn't hit the database, because article_obj.category # has been prepopulated in the previous query. print(article_obj.category) 輸出結果: #能夠看到sql語句中,以最左查詢 LEFT OUTER JOIN 以左表爲主 ''' (0.002) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_ article"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id", "app01_category"."id", "app0 1_category"."title", "app01_category"."blog_id" FROM "app01_article" LEFT OUTER JOIN "app01_category" ON ("app01_article"."category_id" = "app01_category"."id"); args=() yang的web yang的python yang的java None None None None None None None None '''
x
articleList = models.Article.objects.select_related("category").all()
for article_obj in articleList:
# Doesn't hit the database, because article_obj.category
# has been prepopulated in the previous query.
print(article_obj.category)
輸出結果:
#能夠看到sql語句中,以最左查詢 LEFT OUTER JOIN 以左表爲主
'''
(0.002) SELECT "app01_article"."id", "app01_article"."title", "app01_article"."desc", "app01_article"."read_count", "app01_article"."comment_count", "app01_article"."up_count", "app01_
article"."down_count", "app01_article"."create_time", "app01_article"."category_id", "app01_article"."user_id", "app01_article"."site_article_category_id", "app01_category"."id", "app0
1_category"."title", "app01_category"."blog_id" FROM "app01_article" LEFT OUTER JOIN "app01_category" ON ("app01_article"."category_id" = "app01_category"."id"); args=()
yang的web
yang的python
yang的java
None
None
None
None
None
None
None
None
'''