鹽城網(wǎng)站開(kāi)發(fā)英文谷歌優(yōu)化
多表操作
1 基于對(duì)象的跨表查
子查詢(xún)----》執(zhí)行了兩句sql,沒(méi)有連表操作
?2 基于雙下滑線(xiàn)的連表查
一次查詢(xún),連表操作
3 正向和反向
放在ForeignKey,OneToOneField,ManyToManyField的-related_name='books':雙下滑線(xiàn)連表查詢(xún),反向查詢(xún)按表名小寫(xiě)---》用來(lái)替換表名小寫(xiě)publish__books__name-related_query_name='books':基于對(duì)象跨表查,反向查詢(xún)---》用來(lái)替換表名小寫(xiě)pubilsh.book_set.all()pubilsh.books.all()
4聚合查詢(xún)
- aggregate是 QuerySet 的一個(gè)終止子句,用來(lái)做聚合查詢(xún)
- 聚合函數(shù):Avg,Count,Min,Max,Sum
-使用select name,price,avg('price') as price__avg from book; Book.objects.all().aggregate(Avg('price'))select name,price,avg('price') as average_price from book; Book.objects.aggregate(average_price=Avg('price'))ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price'))
5 分組查詢(xún)--》分組后通常會(huì)用聚合---》annotate用來(lái)分組和聚合的
- annotate:
- filter在annotate前:表示過(guò)濾,where條件
- values在annotate前:表示分組的字段,如果不寫(xiě)表示按整個(gè)表分組
- filter在annotate后:表示 having條件
- values在annotate后:表示取字段---》只能取分組字段和聚合函數(shù)字段
- 分組的目的:把有相同特征的分成一組,分成一組后一般用來(lái):統(tǒng)計(jì)總條數(shù),統(tǒng)計(jì)平均數(shù),求最大值
-統(tǒng)計(jì)每一本書(shū)作者個(gè)數(shù)---》 Book.objects.all().values('id').annotate(author_num=Count("authors")).values('name','author_num')-統(tǒng)計(jì)每一個(gè)出版社的最便宜的書(shū)---》按出版社Publish.objects.all().valuse('id').annotate(min_price=Min("book__price")).vlaues('name','min_price')Publish.objects.annotate(MinPrice=Min("book__price"))-查詢(xún)每一個(gè)書(shū)籍的名稱(chēng),以及對(duì)應(yīng)的作者個(gè)數(shù)-->按書(shū)分Book.objects.all().values('id').annotate(count_publish=Count("authors")).value('name','count_publish')-查詢(xún)每一個(gè)以 紅開(kāi)頭 書(shū)籍的名稱(chēng),以及對(duì)應(yīng)的作者個(gè)數(shù)-->按書(shū)分Book.objects.all().filter(name__startswith='紅')values('id').annotate(count_publish=Count("authors")).value('name','count_publish')-查詢(xún)每一個(gè)以 紅開(kāi)頭 書(shū)籍的名稱(chēng),以及對(duì)應(yīng)的作者個(gè)數(shù)大于3的記錄-->按書(shū)分
Book.objects.all().filter(name__startswith='紅')values('id').annotate(count_publish=Count("authors")).filter(count_publish__gt=3).value('name','count_publish')
6 F查詢(xún)與Q查詢(xún)
- F查詢(xún):拿到某個(gè)字段在表中具體的值
-
-查詢(xún)?cè)u(píng)論數(shù)大于收藏?cái)?shù)的書(shū)籍from django.db.models import FBook.objects.filter(評(píng)論數(shù)__gt=F('收藏?cái)?shù)'))-讓所有圖書(shū)價(jià)格 +1Book.objects.all().update(price=F('price')+1)
-
- Q查詢(xún):為了組裝成 ?與 ?或 ?非 條件
-
-與條件:and條件,在filter中直接寫(xiě)---》就是and條件Book.objects.filter(authors__name="lqz",price=100)-或條件:Book.objects.filter(Q(authors__name="lqz")|Q(authors__name="justin"))-非條件:Book.objects.filter(~Q(name='紅樓夢(mèng)'))-復(fù)雜邏輯:(名字為紅樓夢(mèng)并且價(jià)格大于100) 或者 id 大于 2Book.objects.filter((Q(name='紅樓夢(mèng)') & Q(price__gt=100))|Q(nid__gt=2))
-
其他字段和字段參數(shù)
?字段參數(shù);ORM字段參數(shù)
- null用于表示某個(gè)字段可以為空。
- unique 如果設(shè)置為unique=True 則該字段在此表中必須是唯一的 。
- db_index如果db_index=True 則代表著為此字段設(shè)置索引。
- default為該字段設(shè)置默認(rèn)值。
- DateField和DateTimeField
- auto_now_add=True:新增會(huì)把當(dāng)前時(shí)間存入
- default=datatime.datatime.now
- auto_now=True,每次更新數(shù)據(jù)記錄的時(shí)候會(huì)更新該字段
- verbose_name ? ? ? 提示,該字段的作用
- blank ? ? ? ? ? ? ? Admin中是否允許用戶(hù)輸入為空
- editable ? ? ? ? ? ?Admin中是否可以編輯
- help_text ? ? ? ? ? Admin中該字段的提示信息
- choices? ? ? ? ? ? ?Admin中顯示選擇框的內(nèi)容,用不變動(dòng)的數(shù)據(jù)放在內(nèi)存中從而避免跨表操作
- get_字段名_display()
ForeignKey 屬性
? ?to設(shè)置要關(guān)聯(lián)的表
? ?to_field 設(shè)置要關(guān)聯(lián)的表的字段?related_name 反向操作時(shí),使用的字段名,用于代替原反向查詢(xún)時(shí)的’表名_set’。
?related_query_name 反向查詢(xún)操作時(shí),使用的連接前綴,用于替換表名。?on_delete
當(dāng)刪除關(guān)聯(lián)表中的數(shù)據(jù)時(shí),當(dāng)前表與其關(guān)聯(lián)的行的行為。
?models.CASCADE刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)也刪除
?models.DO_NOTHING 刪除關(guān)聯(lián)數(shù)據(jù),引發(fā)錯(cuò)誤IntegrityError
?models.PROTECT 刪除關(guān)聯(lián)數(shù)據(jù),引發(fā)錯(cuò)誤ProtectedError
?models.SET_NULL刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)的值設(shè)置為null(前提FK字段需要設(shè)置為可空)
models.SET_DEFAULT刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)的值設(shè)置為默認(rèn)值(前提FK字段需要設(shè)置默認(rèn)值)?models.SET
刪除關(guān)聯(lián)數(shù)據(jù),
a. 與之關(guān)聯(lián)的值設(shè)置為指定值,設(shè)置:models.SET(值)
b. 與之關(guān)聯(lián)的值設(shè)置為可執(zhí)行對(duì)象的返回值,設(shè)置:models.SET(可執(zhí)行對(duì)象)
?db_constraint---》公司一般都設(shè)置為False
? ? 是否在數(shù)據(jù)庫(kù)中創(chuàng)建外鍵約束,默認(rèn)為T(mén)rue
? ? db_constraint=False ?在數(shù)據(jù)庫(kù)中不建立外鍵約束
?? ?雖然不建立數(shù)據(jù)庫(kù)外鍵約束---》但是orm查詢(xún),繼續(xù)用
ManyToManyField
用于表示多對(duì)多的關(guān)聯(lián)關(guān)系。在數(shù)據(jù)庫(kù)中通過(guò)第三張表來(lái)建立關(guān)聯(lián)關(guān)系
?? ??to 設(shè)置要關(guān)聯(lián)的表,中間是有個(gè)中間表的,區(qū)別于一對(duì)多
?? ??related_name 同F(xiàn)oreignKey字段。
?? ??related_query_name 同F(xiàn)oreignKey字段。
? ??
?? ??through
?? ?在使用ManyToManyField字段時(shí),Django將自動(dòng)生成一張表來(lái)管理多對(duì)多的關(guān)聯(lián)關(guān)系。
?? ?但我們也可以手動(dòng)創(chuàng)建第三張表來(lái)管理多對(duì)多關(guān)系,此時(shí)就需要通過(guò)through來(lái)指定第三張表的表名。
? ? ?through_fields設(shè)置關(guān)聯(lián)的字段。?? ??db_table 默認(rèn)創(chuàng)建第三張表時(shí),數(shù)據(jù)庫(kù)中表的名稱(chēng)。
中間表創(chuàng)建方式
自動(dòng)生成:用不到through 和 ?through_fields
authors=models.ManyToManyField(to='Author',db_table='中間表表名')
- ?自動(dòng)創(chuàng)建中間表,有快捷操作
- add
- remove
- set
- clear
book表id name price1 西游記 222 紅樓夢(mèng) 33bookToauthorsid book_id author_id 1 1 12 1 2author表id name gender age1 lqz 男 182 羅貫中 女 22
手動(dòng)創(chuàng)建中間表,使用through指定
? ? 三張表都要手動(dòng)創(chuàng)建--》3個(gè)類(lèi)--》3個(gè)表模型---》
? ? 什么情況會(huì)使用手動(dòng)創(chuàng)建?----中間表如果有多的字段,都是手動(dòng)創(chuàng)建
authors=models.ManyToManyField(to='Author',through='booktoauthor', through_fields=('當(dāng)前表--》到中間表的外鍵關(guān)系','剩下的寫(xiě)在第二個(gè)位置'))
book表id name price1 西游記 222 紅樓夢(mèng) 33booktoauthorid book_id author_id 日期1 1 1 2 1 2author表id name gender age1 lqz 男 182 羅貫中 女 22
純手動(dòng)創(chuàng)建中間表,不使用ManyToManyField關(guān)聯(lián)
不會(huì)在book或author表中加 ManyToManyField 字段了
book表id name price1 西游記 222 紅樓夢(mèng) 33booktoauthorid book_id author_id 日期1 1 1 2 1 2author表id name gender age1 lqz 男 182 羅貫中 女 22
在表中都可以定義要給內(nèi)部類(lèi) ?
class Author(models.Model):name = models.CharField(max_length=32)class Meta: #元信息db_tableindex_togetherunique_togetherordering # 默認(rèn)按id排序
django與ajax
ajax:異步Javascript和XML
作用:Javascript語(yǔ)言與服務(wù)器(django)進(jìn)行異步交互,傳輸?shù)臄?shù)據(jù)為XML(當(dāng)然,傳輸?shù)臄?shù)據(jù)不只是XML,現(xiàn)在更多使用json數(shù)據(jù))
同步交互,異步交互
?? ?同步交互:js發(fā)送出請(qǐng)求---》直到請(qǐng)求回來(lái)---》頁(yè)面不能操作,不能點(diǎn)擊
? ? 異步交互:js發(fā)出請(qǐng)求---》等待請(qǐng)求回來(lái)的過(guò)程中--->頁(yè)面可以隨意繼續(xù)操作
使用:使用了jq幫咱們封裝的方法 ?ajax ,名字跟ajax相同 $.ajax
真正的ajax原生,需要使用js操作,jq的ajax方法是對(duì)原生js的封裝,方便咱們使用
?? ?-前后端混合項(xiàng)目中,我們通常使用jq的ajax實(shí)現(xiàn) js和后端異步交互
? ? ?? ?-jq操作dom
? ? ? ? -jq發(fā)ajax請(qǐng)求
? ? -前后端分離項(xiàng)目中,我們會(huì)使用另一個(gè)第三方庫(kù),實(shí)現(xiàn) js和后端異步交互(axios)
? ? ?? ?-只想發(fā)送ajax請(qǐng)求---》只用來(lái)發(fā)ajax請(qǐng)求的庫(kù)
計(jì)算 + ?小案例
- demo01.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body><h1>寫(xiě)一個(gè)計(jì)算小案例--ajax</h1>
<input type="text"name="one" id="one"> + <input type="text"name="two" id="two"> = <input type="text"name="three"id="three">
<button id = 'id_btn'>計(jì)算</button>
</body>
<script>$("#id_btn").click(function (){{#alert("xxx")#}var one=$("#one").val()var two=$("#two").val()$.ajax({url:'/demo01/',method:'post',data:{one,two},success:function (res){console.log(typeof res)if (res.code==100){$("#three").val(res.result)}else {alert(res.msg)}}})})
</script>
</html>
- ?views.py
def demo01(requset):if requset.method=='GET':return render(requset,'demo01.html')else:one=int(requset.POST.get('one'))two=int(requset.POST.get('two'))return JsonResponse({'code':100,'msg':'計(jì)算成功','result':one+two})
上傳文件
- demo01.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body><hr>
<h1>文件上傳</h1>
<input type="file" id="id_file"><button id="id_submit">文件上傳</button>
</body>
<script>$("#id_submit").click(function (){{#alert("xxx")#}var formdata = new FormData()//$('#id_file')[0].files[0]//$('#id_file')根據(jù)id拿到標(biāo)簽———》jq把標(biāo)簽放到一個(gè)列表中,//取第0個(gè)位置,是取出第一個(gè)符合條件【id為id_file】的標(biāo)簽,想拿文件---》標(biāo)簽對(duì)象.files--->對(duì)象---》從對(duì)象中取出key為0隊(duì)友的文件對(duì)象formdata.append('myfile',$('#id_file')[0].files[0])$.ajax({url:'/demo01/',method:'post',//指定編碼上傳文件processData: false,contentDocument:false,data:formdata,success:function (res){if (res.code==100){alert(res.msg)}else {alert(res.msg)}}})})
</script>
</html>
- views.py
def demo01(requset):if requset.method=='GET':return render(requset,'demo01.html')else:myfile=requset.FILES.get('myfile')with open(myfile.name,'wb') as f:for line in myfile:f.write(line)return JsonResponse({'code':100,'msg':'文件上傳成功',})
json格式用的多,后期
$.ajax({url: '/demo01/',method: 'post',contentType: 'application/json',data: JSON.stringify({name: 'lqz', age: 19}), // 把對(duì)象轉(zhuǎn)成字符串形式,json格式字符串success: function (data) {console.log(data)}})