Django學習

一 什麼叫Djangocss

  Django是一個開放源代碼的Web應用框架,由Python寫成。採用了MVC的框架模式,即模型M,視圖V和控制器C。它最初是被開發來用於管理勞倫斯出版集團旗下的一些以新聞內容爲主的網站的,便是CMS(內容管理系統)軟件。並於2005年7月在BSD許可證下發布。這套框架是以比利時的吉普賽爵士吉他手Django Reinhardt來命名的。html

  

 

  MVC框架:python

  MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典範,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯彙集到一個部件裏面,在改進和個性化定製界面及用戶交互的同時,不須要從新編寫業務邏輯。MVC被獨特的發展起來用於映射傳統的輸入、處理和輸出功能在一個邏輯的圖形化用戶界面的結構中。
  MVC開始是存在於桌面程序中的,M是指業務模型,V是指 用戶界面,C則是控制器,使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序可使用不一樣的表現形式。好比一批統計數據能夠分別用 柱狀圖餅圖來表示。C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新。
  

 二 Django的簡單介紹git

  Django是一個基於 MVC構造的框架。可是在Django中,控制器接受用戶輸入的部分由框架自行處理,因此 Django 裏更關注的是模型(Model)、模板(Template)和視圖(Views),稱爲 MTV模式。它們各自的職責以下:
  
  從以上表述能夠看出Django 視圖不處理用戶輸入,而僅僅決定要展示哪些數據給用戶,而Django 模板 僅僅決定如何展示Django視圖指定的數據。或者說, Django將MVC中的視圖進一步分解爲 Django視圖 和 Django模板兩個部分,分別決定 「展示哪些數據」 和 「如何展示」,使得Django的模板能夠根據須要隨時替換,而不只僅限制於內置的模板。
至於MVC控制器部分,由Django框架的URLconf來實現。URLconf機制是使用正則表達式匹配URL,而後調用合適的Python函數。URLconf對於URL的規則沒有任何限制,你徹底能夠設計成任意的URL風格,不論是傳統的,RESTful的,或者是另類的。框架把控制層給封裝了,無非與數據交互這層都是數據庫表的讀,寫,刪除,更新的操做。在寫程序的時候,只要調用相應的方法就好了,感受很方便。程序員把控制層東西交給Django自動完成了。 只須要編寫很是少的代碼完成不少的事情。因此,它比MVC框架考慮的問題要深一步,由於咱們程序員大都在寫控制層的程序。如今這個工做交給了框架,僅需寫不多的調用代碼,大大提升了工做效率。

  

  工做機制: 程序員

  1.用manage .py runserver 啓動Django服務器時就載入了在同一目錄下的settings .py。該文件包含了項目中的配置信息,如前面講的URLConf等,其中最重要的配置就是ROOT_URLCONF,它告訴Django哪一個Python模塊應該用做本站的URLConf,默認的是urls .py
  2.當訪問url的時候,Django會根據ROOT_URLCONF的設置來裝載URLConf。
  3.而後按順序逐個匹配URLConf裏的URLpatterns。若是找到則會調用相關聯的視圖函數,並把HttpRequest對象做爲第一個參數(一般是request)
  4.最後該view函數負責返回一個HttpResponse對象。
   

   

 

  

  模型:M正則表達式

  模型是你的數據的惟一的、權威的信息源。它包含你所儲存數據的必要字段和行爲。一般,每一個模型對應數據庫中惟一的一張表。數據庫

  基礎:django

  • 每一個模型都是django.db.models.Model 的一個Python 子類。
  • 模型的每一個屬性都表示爲數據庫中的一個字段。
  • Django 提供一套自動生成的用於數據庫訪問的API

  

 三 Django文檔segmentfault

  1 視圖層跨域

    1)Request對象和Response對象

    Django 使用Request 對象和Response 對象在系統間傳遞狀態。

    當請求一個頁面時,Django會創建一個包含請求元數據的 HttpRequest 對象。 當Django 加載對應的視圖時,HttpRequest 對象將做爲視圖函數的第一個參數。每一個視圖會返回一個HttpResponse 對象。

     HttpRequest對象  

    屬性   

    HttpRequest.method   
    HttpRequest.GET    相似字典的對象
    HttpRequest.POST  相似字典的對象
    HttpResponse對象
     與由Django自動建立的HttpRequest 對象相比,HttpResponse 對象由程序員建立.你建立的每一個視圖負責初始化實例,填充並返回一個 HttpResponse.
    用法
    傳遞字符串
     典型的應用是傳遞一個字符串做爲頁面的內容到HttpResponse 構造函數:
>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the Web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")

 

  2 render()
  help文檔中描述以下: 

  render(request, template_name, context=None, content_type=None, status=None, using=None)

 

  Returns a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments.

 

  此方法的做用---結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。

 

  通俗的講就是把context的內容, 加載進templates中定義的文件, 並經過瀏覽器渲染呈現.

參數講解:

request: 該request用於生成response

template_name: templates 中定義的文件, 要注意路徑名. 好比'templates\polls\index.html', 參數就要寫‘polls\index.html’

context: 要傳入文件中用於渲染呈現的數據, 默認是字典格式

content_type: 生成的文檔要使用的MIME 類型。默認爲DEFAULT_CONTENT_TYPE 設置的值。

status: http的響應代碼,默認是200.

using: 用於加載模板使用的模板引擎的名稱。

  示例:
  
    from django.shortcuts import render  
      
    def my_view(request):  
        # View code here...  
        return render(request, 'myapp/index.html', {  
            'foo': 'bar',  
        }, content_type='application/xhtml+xml')  

 

  3 redirect()重定向
  其實是經歷了兩次請求和響應。
  以login爲例
    第一次請求,method是GET,沒有數據。 /login/--->views.login--->login()
    第二次請求,method是POST,提交數據,字典格式。/login/--->views.login--->login()   。return redirect('/index/')。通知瀏覽器在發送 '/index/'
          請求url  ..../index/,method是GET, 沒有數據。/index/-->views.index-->index(),響應一個index.html頁面、
  
  PS :render與redirect的應用場景:

    若是驗證成功要用redirect跳轉,否則你實際頁面是發生了變化,可是URL仍是沒有變!~

    render()只是對當前訪問模板的加載與渲染,記住!是當前!並不能跳轉!

  4 編寫視圖

  一個視圖函數,簡稱視圖,是一個簡單的Python 函數,它接受Web請求而且返回Web響應。響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西均可以。不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。爲了將代碼放在某處,約定是將視圖放置在項目或應用程序目錄中的名爲views.py的文件中。

  一個簡單的視圖

    下面是一個返回當前日期和時間做爲HTML文檔的視圖:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

讓咱們逐行閱讀上面的代碼:

  • 首先,咱們從 django.http模塊導入了HttpResponse類,以及Python的datetime庫。

  • 接着,咱們定義了current_datetime函數。它就是視圖函數。每一個視圖函數都使用HttpRequest對象做爲第一個參數,而且一般稱之爲request

    注意,視圖函數的名稱並不重要;不須要用一個統一的命名方式來命名,以便讓Django識別它。咱們將其命名爲current_datetime,是由於這個名稱可以精確地反映出它的功能。

  • 這個視圖會返回一個HttpResponse對象,其中包含生成的響應。每一個視圖函數都負責返回一個HttpResponse對象。

四  cmd相關的指令。

  命令行建立Django項目

  在指定的文件夾下 django-admin startproject XXX

  啓動Django項目

  在指定文件夾下  python manage.py runserver

 

五 模板

  模板層

  模板是一個文本,用於分離文檔的表現形式和內容。

  使用模板來輸出數據,從而實現數據與視圖分離。

  在 Django 模板中遍歷複雜數據結構的關鍵是句點字符。很是靈活。列表的索引值,字典的key值,類的靜態屬性,類的動態屬性,均可以是 . 取到。美中不足的是類的動態屬性不能傳參。

  

  點號(.)用來訪問變量的屬性。

  從技術上來講,當模版系統遇到點("."),它將以這樣的順序查詢:

  • 字典查詢(Dictionary lookup)
  • 屬性或方法查詢(Attribute or method lookup)
  • 數字索引查詢(Numeric index lookup)

  若是計算結果的值是可調用的,它將被無參數的調用。調用的結果將成爲模版的值。 -----官方文檔(1.8.2)

  

  模版是純文本文件。它能夠產生任何基於文本的的格式(HTML,XML,CSV等等)。

  模版包括在使用時會被值替換掉的 變量,和控制模版邏輯的 標籤

  模板繼承

  {{ block.super }}繼承模板中原有的內容。

  模板變量用雙括號表示。

  模板標籤

  if/else 標籤

{% if condition %}
     ... display
{% endif %}

   for/empty標籤

  for 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

   

  csrf_token 標籤

  原文博客地址:http://blog.csdn.net/wjtlht928/article/details/46563809

  PS :跨域

    參考博客 :https://segmentfault.com/a/1190000000718840

  CSRF的攻擊原理

  CSRF攻擊原理比較簡單,如圖1所示。其中Web A爲存在CSRF漏洞的網站,Web B爲攻擊者構建的惡意網站,User C爲Web A網站的合法用戶。

1. 用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登陸網站A;

2.在用戶信息經過驗證後,網站A產生Cookie信息並返回給瀏覽器,此時用戶登陸網站A成功,能夠正常發送請求到網站A;

3. 用戶未退出網站A以前,在同一瀏覽器中,打開一個TAB頁訪問網站B;

4. 網站B接收到用戶請求後,返回一些攻擊性代碼,併發出一個請求要求訪問第三方站點A;

5. 瀏覽器在接收到這些攻擊性代碼後,根據網站B的請求,在用戶不知情的狀況下攜帶Cookie信息,向網站A發出請求。網站A並不知道該請求實際上是由B發起的,因此會根據用戶C的Cookie信息以C的權限處理該請求,致使來自網站B的惡意代碼被執行。

  預防措施

  1)在請求地址中添加token並驗證

CSRF攻擊之因此可以成功,是由於攻擊者能夠僞造用戶的請求,該請求中全部的用戶驗證信息都存在於Cookie中,所以攻擊者能夠在不知道這些驗證信息的狀況下直接利用用戶本身的Cookie來經過安全驗證。由此可知,抵禦CSRF攻擊的關鍵在於:在請求中放入攻擊者所不能僞造的信息,而且該信息不存在於Cookie之中。鑑於此,系統開發者能夠在HTTP請求中以參數的形式加入一個隨機產生的token,並在服務器端創建一個攔截器來驗證這個token,若是請求中沒有token或者token內容不正確,則認爲多是CSRF攻擊而拒絕該請求。 

2)在HTTP頭中自定義屬性並驗證  

自定義屬性的方法也是使用token並進行驗證,和前一種方法不一樣的是,這裏並非把token以參數的形式置於HTTP請求之中,而是把它放到HTTP頭中自定義的屬性裏。經過XMLHttpRequest這個類,能夠一次性給全部該類請求加上csrftoken這個HTTP頭屬性,並把token值放入其中。這樣解決了前一種方法在請求中加入token的不便,同時,經過這個類請求的地址不會被記錄到瀏覽器的地址欄,也不用擔憂token會經過Referer泄露到其餘網站。 

六 django的請求生命週期

  首先咱們知道HTTP請求及服務端響應中傳輸的全部數據都是字符串.

  在Django中,當咱們訪問一個的url時,會經過路由匹配進入相應的html網頁中.

  Django的請求生命週期是指當用戶在瀏覽器上輸入url到用戶看到網頁的這個時間段內,Django後臺所發生的事情

  而Django的生命週期內到底發生了什麼呢??

1. 當用戶在瀏覽器中輸入url時,瀏覽器會生成請求頭和請求體發給服務端 請求頭和請求體中會包含瀏覽器的動做(action),這個動做一般爲get或者post,體如今url之中. 2. url通過Django中的wsgi,再通過Django的中間件,最後url到過路由映射表,在路由中一條一條進行匹配, 一旦其中一條匹配成功就執行對應的視圖函數,後面的路由就再也不繼續匹配了. 3. 視圖函數根據客戶端的請求查詢相應的數據.返回給Django,而後Django把客戶端想要的數據作爲一個字符串返回給客戶端. 4. 客戶端瀏覽器接收到返回的數據,通過渲染後顯示給用戶.

  視圖函數根據客戶端的請求查詢相應的數據後.若是同時有多個客戶端同時發送不一樣的url到服務端請求數據

  服務端查詢到數據後,怎麼知道要把哪些數據返回給哪一個客戶端呢??

  所以客戶端發到服務端的url中還必需要包含所要請求的數據信息等內容.

  例如,http://www.aaa.com/index/?nid=user這個url中,
  客戶端經過get請求向服務端發送的nid=user的請求,服務端能夠經過request.GET.get("nid")的方式取得nid數據

  客戶端還能夠經過post的方式向服務端請求數據.

  當客戶端以post的方式向服務端請求數據的時候,請求的數據包含在請求體裏,這時服務端就使用request.POST的方式取得客戶端想要取得的數據

  須要注意的是,request.POST是把請求體的數據轉換一個字典,請求體中的數據默認是以字符串的形式存在的.

  

七 django UR調度器

  視圖層

  文檔網址:http://python.usyiyi.cn/documents/django_182/topics/http/urls.html

  1()位置傳參

  2(?P<x>)關鍵字傳參

  3  URL的反向解析

    在模板中使用 url模板標籤

    urlpatterns=[r'login.html',view.login,name='mylogin']

    模板html文件中

    [form action='{% url 'mylogin'%}']

     <a href='{%url 'myurl'%}'>
 
八 過濾器
  模板層
   Django提供了大約六十個內置的模版過濾器。你能夠在 內置過濾器手冊中閱讀所有關於它們的信息。爲了體驗一下它們的做用,這裏有一些經常使用的模版過濾器。
  內置模板標籤和過濾器官方文檔:http://python.usyiyi.cn/documents/django_182/ref/templates/builtins.html#ref-templates-builtins-filters
  經常使用的有default,filesizeformat,safe等等
 
九 中間件
  在有些場合,須要對Django處理的每一個request都執行某段代碼。 這類代碼多是在view處理以前修改傳入的request,或者記錄日誌信息以便於調試,等等。

這類功能能夠用Django的中間件框架來實現。

  W3C介紹網址:https://www.w3cschool.cn/django/mrxdfozt.html

 

十 Q查詢

  Q 對象是 django.core.meta.Q 的實例, 用來裝載一系列關鍵字參數. 這些關鍵字參數就象指定給 get() 和 filter() 函數的關鍵字參數同樣.舉例來講:

  Q(question__startswith='What') 

  Q 對象可使用 & 和 | 運算符進行組合. 當兩個Q對象進行 & 或 | 運算時,會生成一個新的Q對象.舉例來講語句:

  Q(question__startswith='Who') | Q(question__startswith='What')

  生成一個新的 Q 對象表示這兩個 "question__startswith" 查詢條件的 "OR" 關係. 等同於下面的 SQL WHERE 子句:

  WHERE question LIKE 'Who%' OR question LIKE 'What%'

  示例:

from django.db.models import Q,F
book_list=models.Book.objects.filter(Q(publish__id=2)|Q(price__gt=70))

十一  F查詢

  應用場景 :商品在原價格的基礎上漲價10元

models.Book.objects.update(price=F('price')+10)

 

十二 中介模型

  文檔官方網址:http://python.usyiyi.cn/documents/django_182/topics/db/models.html

  中介模型解決的是當Django幫你建好的多對多模型,並不可以知足,須要添加額外的字段。

  好比Student表,Course表,屬於多對多關係。在Studnet2Course中,想添加一個score字段。

  怎麼解決呢?經過through參數,來告訴Django我本身來建表。

class Student(models.Model):
    name=models.CharField(max_length=10)
    courese=models.ManyToManyField('Course',through='student2course')
    
class Course(models.Model):
    name=models.CharField(max_length=10)
    
class student2course(models.Model):
    student_id=models.ForeignKey('Student')
    course_id=models.ForeignKey('Course')
    score=models.DecimalField(max_digits=4,decimal_places=2)

   

  中介模型有一些限制:

  1 中介模型必須有且只有一個外鍵關聯到源模型上,不然,必須經過manytomanyfield.through_fields()來顯示指定Django 應該在關係中使用的外鍵。

  示例:

  Article與Tag創建多對多 中介模型

class Article(models.Model):

    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=50, verbose_name='文章標題')
    desc = models.CharField(max_length=255, verbose_name='文章描述')

    comment_count= models.IntegerField(default=0)

    homeCategory = models.ForeignKey(to='HomeCategory', to_field='nid', null=True)
    user = models.ForeignKey(verbose_name='做者', to='UserInfo', to_field='nid')
    tags = models.ManyToManyField(
        to="Tag",
        through='Article2Tag',
        through_fields=('article', 'tag'),
    )


在這個中介模型中,有兩個外鍵,怎麼辦呢,用through_fields參數。
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 Meta:
        unique_together = [
            ('article', 'tag'),
        ]
  設置聯合惟一。

 

十三 <QuerySet>轉變爲生成器

  只需調用.iterator()方法

def index(request):
    obj = models.Student.objects.all()
    print(obj, type(obj))
    print(obj.iterator(),type(obj.iterator()))
    return HttpResponse('ok')

  輸出:

<QuerySet [<Student: Student object>, <Student: Student object>]> <class 'django.db.models.query.QuerySet'>
<generator object ModelIterable.__iter__ at 0x000002538633DBA0> <class 'generator'>

 

十四 bulk_create 總體插入

  bulk 大量

  若是插入10000條數據,這樣的方法是不明智的,不合適的

def create(request):
    for i in range(10000):
        User.objects.create_user('user-%s' %i)
    return HttpResponse('ok')

  儘可能少的避免數據的連接與斷開

  推薦這種方法

def create(request):
    l=[]
    for i in range(10000):
        l.append('user-%s' %i)
    User.objects.bulk_create(l)
    return HttpResponse('ok')

 

十五 verbose_name

  自述名

  應用場景:後臺顯示,admin?

  一個字段的可讀性更高的名稱。若是用戶沒有設定冗餘名稱字段,Django會自動將該字段屬性名中的下劃線轉換爲空格,並用它來建立冗餘名稱。

  ForeignKeyManyToManyField 和 OneToOneField 以外,每一個字段類型都接受一個可選的位置參數(在第一的位置) —— 字段的自述名。若是沒有給定自述名,Django 將根據字段的屬性名稱自動建立自述名 —— 將屬性名稱的下劃線替換成空格。

  官方文檔地址:http://python.usyiyi.cn/documents/django_182/topics/db/models.html#verbose-field-names

相關文章
相關標籤/搜索