django

http://docs.30c.org/djangobook2css

MVC 設計模式

首先,咱們分紅4個Python的文件,(models.py ,views.py , urls.py ) 和html模板文件 (latest_books.html )html

  • models.py 文件主要用一個 Python 類來描述數據表。 稱爲 模型(model) 。 運用這個類,你能夠經過簡單的 Python 的代碼來建立、檢索、更新、刪除 數據庫中的記錄而無需寫一條又一條的SQL語句。python

  • views.py文件包含了頁面的業務邏輯。 latest_books()函數叫作視圖mysql

  • urls.py 指出了什麼樣的 URL 調用什麼的視圖。 在這個例子中 /latest/ URL 將會調用 latest_books()這個函數。 換句話說,若是你的域名是example.com,任何人瀏覽網址http://example.com/latest/將會調用latest_books()這個函數。jquery

  • latest_books.html 是 html 模板,它描述了這個頁面的設計是如何的。 使用帶基本邏輯聲明的模板語言,如{% for book in book_list %}nginx

結合起來,這些部分鬆散遵循的模式稱爲模型-視圖-控制器(MVC)。 簡單的說, MVC 是一種軟件開發的方法,它把代碼的定義和數據訪問的方法(模型)與請求邏輯 (控制器)還有用戶接口(視圖)分開來。sql

Django 裏更關注的是模型(Model)、模板(Template)和視圖(Views),Django 也被稱爲 MTV 框架 。在 MTV 開發模式中:數據庫

  • M 表明模型(Model),即數據存取層。 該層處理與數據相關的全部事務: 如何存取、如何驗證有效性、包含哪些行爲以及數據之間的關係等。django

  • T 表明模板(Template),即表現層。 該層處理與表現相關的決定: 如何在頁面或其餘類型文檔中進行顯示。centos

  • V 表明視圖(View),即業務邏輯層。 該層包含存取模型及調取恰當模板的相關邏輯。 你能夠把它看做模型與模板之間的橋樑。

Django基本配置

  Python的WEB框架有Django、Tornado、Flask 等多種,Django相較與其餘WEB框架其優點爲:大而全,框架自己集成了ORM、模型綁定、模板引擎、緩存、Session等諸多功能

一、安裝:
  方式1、pip3 install django
  方式2、官網下載
      解壓
      python3 setup.py install

# 添加環境變量 C:\Python3\Scripts


二、基本操做:

  • 建立project

    先進入本身指定的目錄
    django-admin startproject mysite
  

 

  • 建立app
  cd mysite

  python3 manage.py startapp cmdb

  python3 manage.py startapp monitor

 

  mysite對應的目錄結構

  - mysite (配置文件)

    -init

    -settings 配置文件

    -urls URL對應關係

    -wsgi  遵循WSIG規範,uwsgi+nginx

  - manage.py (管理Project)
  - app(cmdb)
    - models.py 數據庫操做
    - admin.py 配置Django自帶的後臺管理
    - apps.py 當前app的配置
    - tests.py 單元測試
    - views.py 作業務處理...

Django裏面沒封裝socket,當進行socket數據交互時要用到wsgi,生產環境下通常用第三方模塊uwsgi和nginx就能夠把Django程序跑起來

  • 建立templates目錄

    放html文件

    須要在settings.py中加上

'DIRS': [os.path.join(BASE_DIR,'templates')],

 

  • 編輯url.py view.py 

    url是路由系統,每一個url對應view函數處理業務

    view.py  業務處理

      一、return render(request,模板路徑,{'key':'value'})   

      二、return redirect(url) 跳轉

      三、return HttpResponse('ok')

  • 運行
  cd mysite
  python3 manage.py runserver 127.0.0.1:8000

 

1.urls.py下面指定url,一個url對應一個函數 from cmdb import view

2.view.py下面寫函數,return的html會去templates目錄下找

3.settings.py指定了html在templates目錄下,若是POST的方式發送,這行須要註釋,不然forbidden

# 'django.middleware.csrf.CsrfViewMiddleware',

 用戶在瀏覽器中輸入url,看到頁面展現,整個流程

  url.py中匹配對應的路由系統,去view.py中找對應的函數處理,默認method=get,返回templates中的html。

 靜態文件(css,js,圖片)

建立statics文件夾(文件夾名字隨意)

settings.py最後加上

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'statics'),#這裏面的路徑必定是建立的文件
os.path.join(BASE_DIR,'static'),#若是statics和static下面都有相同的js,優先執行statics的,static下面的不執行 )

css

建立commons.css

<link rel="stylesheet" href="/static/commons.css">

js

建立commons.js,記得把jquery也放在此目錄下

{% load staticfiles %}#放在html最上面

<script src="{% static "jquery-1.12.4.js" %}"></script>
<script src="{% static "commons.js"%}"></script>

 

django數據庫操做

  類 --> 數據庫的表

  字段 --> 列

  對象 --> 一行數據

建立數據庫表sqlite

models.py

        class UserInfo(models.Model):
            nid = models.AutoField(primary_key=True)
       user_group = models.ForeignKey('UserGroup') username
= models.CharField(max_length=32) pwd = models.CharField(max_length=64) age = models.IntegerField()
     class UserGroup(models.Model):
       uid = models.AutoField(primary_key=True)
       caption = models.CharField(max_length=64)

*須要在settings.py下  INSTALLED_APPS加上app名字,不然不能建立表

termail下執行

  python3 manage.py makemigrations

  python3 manage.py migrate

須要注意的是,在建立完數據庫後,UserInfo表中會出現user_group_id的字段,user_group存在的,表明UserGroup這個對象

在view.py中,能經過user_group訪問對象的屬性

obj = models.UserInfo.objects.all()

for row in obj:

  row.user_group.uid

  row.user_group.caption

鏈接mysql

*須要本身先建立數據庫

create database day19 charset utf8;

*django鏈接mysql用的是MySqlDB,若是用的是python3的話,須要在配置目錄的init.py中加上:

import pymysql
pymysql.install_as_MySQLdb()

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day19',
        'USER': 'root',
        'PASSWORD': 'centos',
        'HOST': '192.168.147.147',
        'PORT': '3306',
    }
}

數據庫基本操做

a. 查

  models.tb.objects.all()
  models.tb.objects.filter(nid=1)
  models.tb.objects.filter(nid=1).first()

b. 增
  1.models.tb.objects.create(...)
  2.
  obj = models.tb(...)
  obj.save()
c. 刪
  models.tb.objects.all().delete()
  models.tb.objects.filter(nid=1).delete()
d. 改
  models.tb.objects.all().update(...)
  models.tb.objects.filter(nid=1).update(...)

路由系統urls.py

一、單一路由對應

1
url(r '^index$' , views.index),

二、基於正則的路由

1
2
url(r '^index/(\d*)' , views.index),
url(r '^manage/(?P<name>\w*)/(?P<id>\d*)' , views.manage),

利用  url(r'^edit_user_new-(?P<nnid>\d+).html$', views.edit_user_new)實現編輯,url中帶.html覺得是靜態文件,權重會高點。

整個流程  

  user.html中<a href="/edit_user_new-{{ row.nid }}.html">新編輯</a>

  新編輯跳轉到這個url,url.py中加url(r'^edit_user_new-(?P<nnid>\d+).html$', views.edit_user_new)

  views.py中def edit_user_new(request,nnid)須要帶上參數,method是GET

  編輯完以後提交,action="/edit_user_new-{{ obj.nid }}.html"

  

三、添加額外的參數

1
url(r '^manage/(?P<name>\w*)' , views.manage,{ 'id' : 333 }),

四、爲路由映射設置別名

1
2
url(r '^home' , views.home, name = 'h1' ),
url(r '^index/(\d*)' , views.index, name = 'h2' ),

h1就代指這個url

<form method="POST" action="{% url 'nnn' nnid=obj.nid %}">

設置名稱以後,能夠在不一樣的地方調用,如:

  • 模板中使用生成URL     {% url 'h2' 2012 %}
  • 函數中使用生成URL     reverse('h2', args=(2012,))      路徑:django.urls.reverse
  • Model中使用獲取URL  自定義get_absolute_url() 方法

五、根據app對路由規則進行分類

1
url(r '^app01/' ,include( 'app01.urls' )),

當訪問127.0.0.1:8000/app01/user時,先去匹配前面的app01,而後去app01下面的url.py中匹配

六、命名空間

a. project.urls.py

1
2
3
4
5
6
from  django.conf.urls  import  url,include
 
urlpatterns  =  [
     url(r '^a/' , include( 'app01.urls' , namespace = 'author-polls' )),
     url(r '^b/' , include( 'app01.urls' , namespace = 'publisher-polls' )),
]

b. app01.urls.py

1
2
3
4
5
6
7
from  django.conf.urls  import  url
from  app01  import  views
 
app_name  =  'app01'
urlpatterns  =  [
     url(r '^(?P<pk>\d+)/$' , views.detail, name = 'detail' )
]

c. app01.views.py

1
2
3
def  detail(request, pk):
     print (request.resolver_match)
     return  HttpResponse(pk)

以上定義帶命名空間的url以後,使用name生成URL時候,應該以下:

  • v = reverse('author-polls:detail', kwargs={'pk':11})
  • {% url 'app01:detail' pk=12 pp=99 %}

django中的路由系統和其餘語言的框架有所不一樣,在django中每個請求的url都要有一條路由映射,這樣才能將請求交給對一個的view中的函數去處理。其餘大部分的Web框架則是對一類的url請求作一條路由映射,從而是路由系統變得簡潔。

視圖函數views.py

  獲取請求信息:
    request.POST {'username':'root'..}
    request.GET
    request.FILES

      obj = request.FILES.get(input裏面的name)

      文件名 obj.name

      for line in obj.chunks()

    request.method
    request.body = username=root;age=18;gender=male

  響應結果:
    return HttpReponse(..)
    return render(request,'path/a.html',{})
    return redirect('http://www.baidu.com')

模板

 模板中也有本身的語言,該語言能夠實現數據展現

  • {{ item }}
  • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
      forloop.counter
      forloop.first
      forloop.last 
  • {% if ordered_warranty %}  {% else %} {% endif %}
  • extend

    母板:{% block title %}{% endblock %}
    子板:{% extends "base.html" %}
       {% block title %}新內容{% endblock %}

  • include

    子板:{% extends "base.html" %}
       {% block title %}新內容{%include 'small.html'%}{% endblock %} 

  • 字典.key   列表.索引
  • 幫助方法:
    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}

三、自定義simple_tag(頁面展現)

a、在app中建立templatetags模塊

b、建立任意 .py 文件,如:xx.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
#coding:utf-8
from  django  import  template
from  django.utils.safestring  import  mark_safe
   
register  =  template.Library()
   
@register .simple_tag
def  my_simple_time(v1,v2,v3):
     return   v1  +  v2  +  v3
   
@register .simple_tag
def  my_input( id ,arg):
     result  =  "<input type='text' id='%s' class='%s' />"  % ( id ,arg,)
     return  mark_safe(result)
from django import template
from django.utils.safestring import mark_safe
register = template.Library()

@register.filter()

def anyway(value,num):
    return 'dassssssssssssssssssssssssssss'+value+str(num)
@register.filter()
def ya(value,v):
    temp = "<a href='http://www.baidu.com?t=%s'>%s</a>"%(v,value)
    return mark_safe(temp)

 

c、在使用自定義simple_tag的html文件中導入以前建立的 xx.py 文件名

1
{ %  load xx  % }

d、使用simple_tag

1
2
{ %  my_simple_time  1  2  3 % }
{ %  my_input  'id_username'  'hide' % }

e、在settings中配置當前app,否則django沒法找到自定義的simple_tag  

1
2
3
4
5
6
7
8
9
INSTALLED_APPS  =  (
     'django.contrib.admin' ,
     'django.contrib.auth' ,
     'django.contrib.contenttypes' ,
     'django.contrib.sessions' ,
     'django.contrib.messages' ,
     'django.contrib.staticfiles' ,
     'app01' ,
)

四、自定義filter(在if條件中作條件時)

{{ summary|anyway:8 }}

在頁面僅顯示內容用simple_tag

 cookie

  - 是用戶瀏覽器上的一個鍵值對
  - 設置超時時間

  利用cookie可實現:
    - 登陸驗證
    - 頁面顯示條數
    - 拖動位置..

  兩大忌諱:
    - 敏感信息
    - 簡單

一、獲取Cookie:

1
2
3
4
5
6
request.COOKIES.get( 'key')
request.get_signed_cookie(key, default = RAISE_ERROR, salt = '', max_age = None )
     參數:
         default: 默認值
            salt: 加密鹽
         max_age: 後臺控制過時時間

二、設置Cookie:

1
2
3
4
5
6
7
8
9
10
11
12
13
rep  =  HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect(url)
 
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt = '加密鹽' ,...)
     參數:
         key,              鍵
         value = '',         值
         max_age = None ,     超時時間
         expires = None ,     超時時間(IE requires expires, so  set  it  if  hasn't been already.)
         path = '/' ,         Cookie生效的路徑, /  表示根路徑,特殊的:跟路徑的cookie能夠被任何url的頁面訪問
         domain = None ,      Cookie生效的域名
         secure = False ,     https傳輸
         httponly = False     只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)

因爲cookie保存在客戶端的電腦上,因此,JavaScript和jquery也能夠操做cookie。

1
2
<script src = '/static/js/jquery.cookie.js' >< / script>
$.cookie( "list_pager_num" 30 ,{ path:  '/'  });

  設置cookie

    obj = redirect('/app02/groups')
    obj.set_cookie(key='user_name',value=u,max_age=10)
    return obj

  獲取cookie

    request.COOKIES.get('user_name')

session

session依賴cookie

SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默認)

SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認)
SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時(默認)
SESSION_SAVE_EVERY_REQUEST = False

 生成隨機字符串保存在客戶端,服務器端保存形式字典,{'隨機字符串':{'username':'root','password':'pwd'}}

  request.session['user'] = u

  v = request.session.get('user')

裝飾器+session實現登陸認證

from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import HttpResponse

from app01 import models
# Create your views here.
def auth(func):
    def inner(request,*args,**kwargs):
        v = request.session.get('user')
        if not v:
            return redirect('/app02/login')
        else:
            return func(request,*args,**kwargs)
    return inner
@auth
# group = auth(group)
def group(request):
    # # v = request.session.get('username')
    # if not v:
    #     return redirect('/app02/login')
    # else:
    return render(request,'groups.html')
@auth
def user(request):
    return render(request,'user.html')

def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    elif request.method == 'POST':
        u = request.POST.get('username')
        p = request.POST.get('pwd')
        v = models.UserInfo.objects.filter(username=u,pwd=p).first()
        if v:
            obj = redirect('/app02/groups')
            # obj.set_cookie(key='user',value=u,max_age=10)
            request.session['user'] = u
            return obj
        else:
            return render(request, 'login.html',{'msg':'用戶名或密碼錯誤'})

主要加了個auth函數,auth函數功能,取session,有執行func,沒有的話跳轉到login

相關文章
相關標籤/搜索