orm表關(guān)系如何建立一對一一張表的字段信息太多,,可以人為分出一張表 一對多外鍵字段建在 多的那一方 多對多多對多的外鍵關(guān)系需要建立第三張表來專門處理 以圖書館里系統(tǒng)為例,創(chuàng)建圖書表,,作者表,,出版社表 以圖書管理系統(tǒng)為例,在django orm 建立表關(guān)系: 一對一的表關(guān)系,,外鍵字段建在任意一方都可以,,但是建議建在查詢頻率較高的一方 書與出版社是一對多關(guān)系,,并且書是多的一方,所以外鍵字段建在書表中 書與作者是多對多的關(guān)系,, 外鍵字段建在任意一方都可以,建議建在查詢頻率較高的一方
class Book(models.Model):
title = models.CharField(max_length=32) # 小數(shù)總共八位,,小數(shù)占兩位
price = models.DecimalField(max_digits=8, decimal_places=2) # 書與出版社是一對多關(guān)系,,并且書是多的一方,所以外鍵字段建在書表中
publish = models.ForeignKey(to='Publish') # to用來指代和哪張表有關(guān)系,默認(rèn)關(guān)聯(lián)的就是主鍵字段
# 書與作者是多對多的關(guān)系,, 外鍵字段建在任意一方都可以,,建議建在查詢頻率較高的一方
author = models.ManyToManyField(to='Author') # django orm會自動幫你創(chuàng)建書和作者的第三張關(guān)系表
# author這個(gè)字段是一個(gè)虛擬字段 不能在表中展示出來,僅僅只是告訴orm,,建立第三張表關(guān)系的作用class Publish(models.Model):
title = models.CharField(max_length=32)
email = models.EmailField()class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField() # 一對一的表關(guān)系,,外鍵字段建在任意一方都可以,但是建議建在查詢頻率較高的一方
author_detail = models.OneToOneField(to='Author_detail')class Author_detail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)
注意點(diǎn): 一對多外鍵字段 創(chuàng)建的時(shí)候 ,,同步到數(shù)據(jù)庫中,,表字段會自動加_id 后綴;如果自己加了_id ,,會在后面再加一個(gè)_id publish = models.ForeignKey(to='Publish') 默認(rèn)關(guān)聯(lián)的是主鍵id,,如果主鍵不是id,要自己關(guān)聯(lián),, 可以加to_field= 于指定字段做關(guān)聯(lián)
django請求生命周期流程圖url.py路由層urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'test/', views.test),
url(r'testadd/', views.testadd)
]
如果url.py這樣寫,,test 和testadd 后綴的訪問路徑,返回的內(nèi)容是一樣的,,原因如下: url第一個(gè)參數(shù)是一個(gè)正則表達(dá)式 一旦正立刻結(jié)束則表達(dá)式能夠匹配到內(nèi)容,,會立刻結(jié)束匹配關(guān)系,直接執(zhí)行后面對應(yīng)的函數(shù)
路由匹配啟動django,,在瀏覽器輸入127.0.0.1:8000/test ,,django會自動加斜杠。 django匹配路由規(guī)律不加斜杠(127.0.0.1:8000/test ),,先匹配一次試試,,如果匹配不上,會讓瀏覽器重定向,,加一個(gè)斜杠(127.0.0.1:8000/test/ )再來一次匹配,,如果還匹配不上,才會報(bào)錯(cuò),。 取消django自動讓瀏覽器加斜杠的功能在配置文件中settings.py中添加: APPEND_SLASH = False # 該參數(shù)默認(rèn)為True
限制指定輸入的urlurlpatterns = [
url(r'^admin/', admin.site.urls), # url第一個(gè)參數(shù)是一個(gè)正則表達(dá)式
url(r'^test/$', views.test), # 一旦正立刻結(jié)束則表達(dá)式能夠匹配到內(nèi)容,,會立刻結(jié)束匹配關(guān)系,直接執(zhí)行后面對應(yīng)的函數(shù)
url(r'^testadd/$', views.testadd)
]
這樣設(shè)置,,只能輸入127.0.0.1:8000/test/ 或127.0.0.1:8000/testadd/ 注意:路由匹配只是匹配URL部分,,不匹配get攜帶的參數(shù) ?后面的參數(shù) 無名分組正則表達(dá)式的無名分組 urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/([0-9]{4})', views.test), # 表示test后面跟4個(gè)數(shù)字
url(r'^testadd/', views.testadd)
]
當(dāng)你的路由中有分組的正則表達(dá)式,那么在匹配到內(nèi)容執(zhí)行視圖函數(shù)的時(shí)候,,會將分組內(nèi)正則表達(dá)式匹配到的內(nèi)容當(dāng)作位置參數(shù)傳遞給視圖函數(shù),。 # 在視圖函數(shù)def test(request, xxx):
print('多余的參數(shù):', xxx) return HttpResponse('test view')
有名分組urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/(\d+)/', views.test),
url(r'^testadd/(?P<year>\d+)/', views.testadd) # 正則表達(dá)式有名分組]
當(dāng)你的路由中有分組并且給分組起了別名,那么在匹配內(nèi)容的時(shí)候,,會將分組內(nèi)的正則表達(dá)式匹配到的內(nèi)容當(dāng)作關(guān)鍵字參數(shù)傳遞給視圖函數(shù) # 在視圖函數(shù)def test(request, year):
print('多余的參數(shù):', year) return HttpResponse('test view')
這樣就可以利用有名和無名分組,,我們就可以在調(diào)用視圖函數(shù)之前給函數(shù)傳遞額外的參數(shù) 注意:有名分組和無名分組不能混合使用,,但是同一情況下,無名分組可以使用多次,,又名分組也可以使用多次 反向解析舉個(gè)例子: # urls.pyurlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/(\d+)/', views.test),
url(r'^testadd/(?P<year>\d+)/', views.testadd),
url(r'^index/', views.index),
url(r'^home/', views.home),
]# views.pydef index(request):
return render(request, 'index.html')def home(request):
return HttpResponse('home')
在上述代碼中,,index.html 頁面中有很多跳轉(zhuǎn)的鏈接,都指向home 路由,。如果像改變home 的url地址,,那么index.html 頁面中的很多跳轉(zhuǎn)home 的鏈接都有改變,有沒有動態(tài)綁定url地址的方法呢,?反向解析就是,。 定義反向解析:根據(jù)一個(gè)別名,動態(tài)解析出一個(gè)結(jié)果,,該結(jié)果可以直接訪問對應(yīng)的url 路由中沒有正則表達(dá)式,,直接就是寫死的url(r'^home/', views.home,name='xxx'), # 給路由與視圖函數(shù)對應(yīng)關(guān)系起別名
前端反向解析<p><a href="{% url 'xxx'%}">111</a></p>
后端反向解析from django.shortcuts import render,HttpResponse,redirect,reversedef get_url(request):
url = reverse('xxx')
print(url) return HttpResponse('get_url')
無名分組的反向解析在解析的時(shí)候,你需要手動指定正則匹配內(nèi)容的是什么 url(r'^home/(\d+)/', views.home, name='xxx'),
前端反向解析<p><a href="{% url 'xxx' 12 %}">111</a></p>
后端反向解析def get_url(request):
url = reverse('xxx', args=(1,))
url2 = reverse('xxx', args=(1231,))
print(url)
print(url2) return HttpResponse('get_url')
手動傳入的參數(shù) 只需要滿足 能夠被正則表達(dá)式匹配即可 有名分組的反向解析url(r'^home/(?P<year>\d+)/', views.home, name='xxx'),
前端反向解析可以直接用無名分組的情況 <p><a href="{% url 'xxx' 12 %}">111</a></p>
規(guī)范的寫法: <p><a href="{% url 'xxx' year=121 %}">111</a></p>
后端反向解析可以直接用無名分組的情況 也可以規(guī)范寫: def get_url(request):
url = reverse('xxx', kwargs={'year': 13123})
print(url) return HttpResponse('get_url')
以編輯功能為例,,反向解析的應(yīng)用# urls.pyurl = (r'^edit_user/(\d+)/', views.edit_user, name='edit')# views.pydef edit_user(request, edit_id): # edit_id就是用戶想要編輯數(shù)據(jù)主鍵值
pass
<!--頁面-->{% for user_obj in user_list %}<a href='/edit_user/{{user_obj.id}}/'>編輯</a><a href='{% url 'edit' user_obj.id %}'>編輯</a>{% endfor %}
路由分發(fā)前提: 在django中所有的app都可以有自己獨(dú)立的urls.py \ templates \ static.
正是由于上面的特點(diǎn) 你用django開發(fā)項(xiàng)目就能夠完全做到多人分組開發(fā) 互相不干擾,每個(gè)人只開發(fā)自己的app.
小組長只需要將所有人開發(fā)的app整合到一個(gè)空的django項(xiàng)目里面,
然后在settings配置文件注冊 再利用路由分發(fā)將多個(gè)app整合到一起即可完成大項(xiàng)目的拼接
路由分發(fā)解決的就是 項(xiàng)目的總路由 匹配關(guān)系過多的情況,, 使用路由分發(fā), 會出現(xiàn): 總路由不再做匹配的活 而僅僅是做任務(wù)分發(fā) 請求來了之后 總路由不做對應(yīng)關(guān)系,,只詢問你要訪問哪個(gè)app的功能 然后將請求轉(zhuǎn)發(fā)給對應(yīng)的app去處理
使用: 總路由 (include)只需要將所有的app的urls.py導(dǎo)入即可 from django.conf.urls import url, includefrom app01 import urls as app01_urlsfrom app02 import urls as app02_urls
urlpatterns = [
url(r'^app01/', include(app01_urls)),
url(r'^app02/', include(app02_urls)),
]# 路由分發(fā)
子路由# app01 urls.pyfrom django.conf.urls import urlfrom app01 import views
urlpatterns = [
url(r'^reg/', views.reg),
]# app02 urls.pyfrom django.conf.urls import urlfrom app02 import views
urlpatterns = [
url(r'^reg/', views.reg),
]
最省事的寫法: # 連導(dǎo)入都不需要url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
名稱空間 (namespace)當(dāng)多個(gè)app中出現(xiàn)了起別名沖突的情況 你在做路由分發(fā)的時(shí)候 可以給每一個(gè)app創(chuàng)建一個(gè)名稱空間 然后在反向解析的時(shí)候 可以選擇到底去哪個(gè)名稱空間中查找別名 在總路由中: url(r'^app01/',include('app01.urls',namespace='app01')),
url(r'^app02/',include('app02.urls',namespace='app02'))
前端: <a href="{% url 'app01:reg' %}"></a><a href="{% url 'app02:reg' %}"></a>
后端: print(reverse('app01:reg'))
print(reverse('app02:reg'))
但是也可以不用,,你只要 保證起別名的時(shí)候,在整python基礎(chǔ)教程個(gè)django項(xiàng)目中不沖突即可 偽靜態(tài)就是將一個(gè)動態(tài)網(wǎng)頁偽裝成一個(gè)靜態(tài)網(wǎng)頁,,這樣可以便于搜索引擎SEO(Search Engine Optimization),,提高搜索引擎的收藏力度。 虛擬環(huán)境django版本區(qū)別在urls.py 中路由匹配的方法有區(qū)別 django 1.xx版本用的是url from django.conf.urls import url
urlpatterns = [
url(r'^reg.html',views.reg,name='app01_reg')
]
django 2.xx版本用的是path from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
這里的path第一個(gè)參數(shù)不是正則,,也不支持正則 django2.X還有一個(gè)re_path的方法 該方法就是django1.X里面url path提供了五種轉(zhuǎn)換器,,能夠?qū)⑵ヅ涞降臄?shù)據(jù)自動轉(zhuǎn)換成對應(yīng)的類型 還支持自定義的轉(zhuǎn)換器
django后端獲取文件對象form表達(dá)傳文件需要注意的事項(xiàng) method必須改成post enctype改為formdata格式
# urls.pyfrom django.conf.urls import urlfrom app02 import views
urlpatterns = [
url(r'^upload/', views.upload)
]# views.pydef upload(request):
if request.method == 'POST':
print(request.FILES) # django會將文件類型的數(shù)據(jù)自動放入request.FILES
file_obj = request.FILES.get('myfile') # 文件對象
# print(file_obj)
# print(file_obj.name)
with open(file_obj.name, 'wb') as f: for line in file_obj:
f.write(line) return render(request, 'upload.html')
|