2019-03-26 Django大綱

Django

虛擬環境

創建:virtualenv --no-site-packages -p python.exe的路徑 環境名

安裝與使用

安裝:pip install django==2.1.7

創建Django項目:django-admin startproject 項目名

創建django應用:python manage.py startapp 應用名

啟動,修改IP和端口

  • 修改端口:python manage.py runserver 端口號

  • 修改IP和端口:python manage.py runserver IP:端口號

數據庫簡單配置與遷移

  • 修改settings.py文件中DATABASE的數據:NAME,USER,PASSWORD,HOST,PORT,OPTIONS

  • 不管用不用,都必須遷移默認的模型 遷移django默認提供的模型:python manage.py migrate

管理后臺

  • 訪問:IP:端口/admin/

  • 創建賬號:python manage.py createsuperuser

模型

遷移

  • 生成遷移文件: python manage.py makemigrations

  • 執行遷移文件:python manage.py migrate

  • 注意:當第一次遷移Django默認提供的表時,直接執行migrate命令即可

模型定義

  • 字段定義

    • IntegerField:整型字段

    • CharField:字符串

    • BooleanField:布爾值

    • DateTimeField:年月日時分秒字段

    • DateField:年月日

    • TimeField:時間戳

    • ImageField:圖片

    • FloatField:浮點數

    • DecimalField:浮點數,指定了長度的浮點數

    • TextField:文本,textarea

    • AutoField:自增字段,不用定義

  • 約束定義

    • max_length:最大長度

    • min_length:最小長度

    • unique:是否唯一

    • null:是否為空

    • default:默認值

    • auto_now_add和auto_now:互斥

模型操作

    • 對象.save()

    • 模型.objects.create(字段1=值1,字段2=值2,...)

    • 對象.delete()

    • 模型.objects.filter().delete()

    • 修改的對象.save()

    • 模型.objects.filter().update(字段1=值1,字段2=值2,...)

    • all():queryset結果

    • first():取結果中第一個對象

    • last():取結果中最后一個對象

    • 模型.objects.filter(字段='值')

    • 模型.objects.get(條件)

      • 條件必須成立

      • 查詢結果只有一個

    • exclude(條件):過濾不滿足條件的信息

    • count():查詢結果的個數

    • values('字段'):將對象的內容序列化成字典/json

    • order_by('字段')

      • 升序:order_by('字段')

      • 降序:order_by('-字段')

    • contains:包含

      • 模型.objects.filter(字段__contains='值')
    • startswith:以什么開頭

    • endswith:以什么結尾

    • 大小于

      • 大于,大于等于:gt,gte

      • 小于,小于等于:lt, lte

    • aggregate:聚合

      • Avg, Sum, Count, Max, Min
    • F:對比兩個屬性字段,可以進行加減算法

      • 模型.objects.filter(字段1__gt=F('字段2'))
    • Q:用于與或非

      • 或:Q(條件1) | Q(條件2)

      • 非:~Q(條件1)

模型關系

一對一

  • OneToOneField(關聯模型)

  • 模型定義

    class A(): id = models.IntegerField()

    class B(): aa = models.OneToOneField(A, related_name='cc')

    已知:A對象a,查詢B對象 related_name沒定義時: a.b related_name已定義時: a.cc

    已知:B對象b,查詢A對象 b.aa

  • 注意:OneToOneField定義的字段可以寫在關聯模型的任意一方

一對多

  • ForeignKey(關聯模型)

  • 模型定義

    class A(): id

    class B(): aa = ForeignKey(A, related_name='cc')

    已知:A對象a,查詢B對象 related_name沒定義時: a.b_set.all() related_name已定義時: a.cc.all()

    已知:B對象b,查詢A對象 b.aa

  • 注意:ForeignKey定義的字段表示多的對方,因此只能放在'多'的模型中

多對多

  • ManyToManyField(關聯模型):會自動生成中間表

  • 模型定義

    class A(): id

    class B(): aa = ManyToMany(A, related_name='cc')

    已知:A對象a,查詢B對象 related_name沒定義時: a.b_set.all()

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n198" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">related_name已定義時:
    a.cc.all()</pre>

    已知:B對象b,查詢A對象 b.aa.all()

  • 注意:ManyToMany定義的字段可以寫在關聯模型的任意一方

  • 中間表的添加:add()、刪除:remove()

字段中的on_delete參數值

  • models.CASCADE: 表示主鍵所在行的數據被刪,外鍵所在行的數據也會被刪,是完全關聯在一起的

  • models.PROTECT: 表示主鍵作為外鍵存在別的表中時,不讓刪除主鍵的數據

  • models.SET_NULL: 表示主鍵刪除,外鍵置空

模板

父模板:用于挖坑{% block name %} {% endblock %}

子模板:負責繼承父模板后,進行填坑

標簽:{% 標簽 %}

  • {% extends '父模板' %}

  • {% block name %} {% endblock %}

  • {% if 條件 %} {% else %} {% endif %}

  • {% ifequal 變量 值 %} {% endifequal %}

  • {% for i in [] %} {% endfor %}

  • 解析靜態文件地址: {% static 'css/xxx.css' %} 繼承模板的時候,要有: {% load static %}

  • 解析路由地址: {% url 'user:index' %}

變量:{{ 變量名 }}

  • {{ forloop.counter }}

  • {{ forloop.counter0 }}

  • {{ forloop.revcounter }}

  • {{ forloop.revcounter1 }}

  • {{ forloop.first }}

  • {{ forloop.last }}

  • {{ stu.course.all }}:通過學生查詢所有的課程信息

  • {{ stu.course.下標 }}

過濾器

  • 定義:使用管道符 '|'

路由規則

path

re_path

  • /(\d+)/(\w+)/

  • (?P<參數名>\d+)

include

urlpatterns = [ path('admin/', admin.site.urls), # 包含 # TODO:Django2.0以下寫法, path('goods/', include('goods.urls')), path('app/', include('app.urls')) ]

  • 拆分路由地址,將不同應用的URL文件進行拆分

請求與響應

請求

  • method:判斷請求方式,主要GET/POST

  • path:獲取訪問的路由地址

  • FILES:獲取圖片或文件的信息

  • GET:獲取get請求方式的數據

    • get()

    • getlist()

  • POST:獲取post請求方式的數據

  • COOKIES:cookie內容

  • session:存儲在服務端的數據

響應

  • 跳轉:HttpResponseRedirect()

    • 無參

      • HttpResponseRedirect(reverse('namespace:name'))
    • 有參

      • HttpResponseRedirect(reverse('namespace:name', kwargs={'參數名': '值'}))

      • HttpResponseRedirect(reverse('namespace:name', args=(值, )))

    • 頁面反向解析

      • {% url 'namespace:name' 值1 值2 值3 ... %}
  • JsonResponse():響應json格式的數據

  • HttpResponse(字符串)

  • render(頁面)

用戶USER

使用django自帶的USER模塊

  • 注冊:User.objects.create_user()

  • 校驗:user = auth.authenticate(username, password)

  • 登錄:auth.login(request, user)

  • 退出:auth.logout(requset)

  • 裝飾器:login_required() 要配合在setting里面設置才有用: LOGIN_URL = '/user/login/'

自定義USER模塊

  • 登錄:request.session['user_id'] = user.id 添加鍵值對的時候,同時會把數據庫中創建的session_key傳給瀏覽器

  • 退出

    • request.session.flush() 同時刪除數據庫和瀏覽器中的session

    • request.session.delete(session_key) 刪除數據庫中對應的session記錄

    • del request.session['user_id'] 刪除數據庫中之前添加的鍵值對,相當于刪除瀏覽器識別session的唯一標識

  • 裝飾器

    from django.http import HttpResponseRedirect from django.urls import reverse

    from user.models import MyUser

    def is_login(func):

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n352" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;">def check(request, *args, **kwargs):

    登錄的校驗

    if 'user_id' in request.session:
    user = MyUser.objects.get(pk=request.session['user_id'])
    request.user = user
    return func(request, *args, **kwargs)
    else:
    return HttpResponseRedirect(reverse('user:my_login'))
    ?
    return check</pre>

中間件MIDDLEWARE

process_request(self, request):請求進來時直接進行攔截(應用場景:登錄校驗)

process_view(self, request, view_func, view_args, view_kwargs):調用view方法之前進行攔截調用

process_exception(self, request, exception):不主動調用,只有出現異常時才執行

process_response(self, response):最后響應瀏覽器時才調用

process_template_response():沒有應用場景

執行順序

  • 中間件按照排列順序,從上往下依次執行process_request(), 如果返回None表示繼續訪問中間件或者方法, 如果return HttpResponse() 表示直接響應內容給瀏覽器

  • process_request()執行完畢后,從上往下執行process_view()

  • 前面的方法沒有返回響應時,從下往上執行process_response()

文件上傳

安裝:pip install pillow

模型中定義字段:

icon = models.ImageField(upload_to='upload')

設置media文件夾路徑:

MEDIA_URL = 'media' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

展示圖片需要在工程目錄的urls.py文件中指定靜態文件路由:

static(MEDIA_URL, document_root=MEDIA_ROOT)

展示圖片:

前端中定義屬性<form enctype='multipart/form-data'>

表單驗證

定義

class UserForm(forms.Form):
forms.CharField
forms.IntegerField
forms.ImageField

def clean(self):
    # 自動調用
    return self.cleaned_data

def clean_字段(self):
    # 校驗指定字段
    return self.cleaend_data

?

forms = UserForm(request.POST, request.FILES)

驗證:form.is_valid()

驗證錯誤信息:form.errors

分頁

from django.core.paginator import Paginator

paginator = Paginator(所有數據,條數)

  • 查看總頁數:paginator.num_pages

  • 獲取某一頁的數據: page_data = paginator.page(頁碼)

  • paginator.page_range:相當于range(1,總頁碼數)

page_data = paginator.page(頁碼)

越界會報錯

  • page_data.has_next():是否有下一頁

  • page_data.has_previous:是否有上一頁

  • page_data.next_page_number:下一頁頁碼

  • page_data.previous_page_number:上一頁頁碼

  • page_data.paginator:獲取paginator對象

權限

RBAC

用戶表--權限表--角色表:

都是多對多關聯關系

用戶和權限:user_permissions字段

用戶和角色:groups字段

角色和權限:permissions字段

權限列表

  • 1.通過用戶查詢權限表

  • 2.通過用戶查詢角色,角色查詢權限

權限獲取

  • 獲取所有權限:包括用戶對應角色權限和用戶對應權限表,user.get_all_permissions()

  • 獲取用戶組權限:user.get_group_permissions()

權限校驗裝飾器

  • @permission_required('應用名.權限名')

模板中

  • 解析當前用戶的權限,是個集合: {{ perms.user }}:{'應用名.權限名'}

  • {% if perms.user.add_users %}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 茶點故事閱讀 47,953評論 2 373

推薦閱讀更多精彩內容