Python的重要知識點彙總2

使用socket 模擬服務器 給 瀏覽器 發 數據:

 1 import socket
 2 
 3 sk = socket.socket()
 4 sk.bind(('127.0.0.1',8080))
 5 sk.listen()
 6 
 7 while 1:
 8     conn, addr = sk.accept()
 9     d = conn.recv(1024)
10     # print(d.decode())
11     conn.send(b'HTTP/1.1 200 OK\r\n\r\n') # 和 瀏覽器通訊 要遵照 http 協議
12     conn.send(b'<h1>Welcome come to my site! </h1>')
13     print('haha')
14 
15     conn.close()
16 sk.close()
17 
18 
19 # http 協議
20 '''
21 GET / HTTP/1.1
22 
23 '''
24 '''
25 HTTP/1.1 200 OK
26 
27 hello world
28 '''
server.py

此時 瀏覽器 輸入 127.0.0.1:8080 就能夠訪問收到 咱們回覆的內容了, css

Django 框架: 

目錄:https://www.cnblogs.com/clschao/articles/10526431.htmlhtml

 

 

簡單 web框架: 

Django基礎一之web框架的本質: https://www.cnblogs.com/clschao/articles/10391859.html前端

 1 from wsgiref.simple_server import make_server
 2 from op_db import getUserData
 3 from jinja2 import Template
 4 
 5 def index():
 6     # {'id': 1, 'name': 'tom', 'age': 18}
 7     userinfo = getUserData()
 8     print(userinfo)
 9     with open("index.html","rb") as f:
10         d = f.read()
11 
12     tpl_str = Template(d.decode())
13     ret = tpl_str.render({'data':userinfo})
14     return ret.encode()
15 
16 
17 def ico():
18     with open("favicon.ico","rb") as f:
19         d = f.read()
20     return d
21 
22 def application(environ, start_response):
23     start_response('200 OK', [('k1','v1'),])
24     path = environ['PATH_INFO']
25 
26     urlpatterns = [
27         ('/',index),
28         ('/favicon.ico', ico),
29     ]
30     for i in urlpatterns:
31         if i[0] == path:
32             data = i[1]()
33     return [data]
34 
35 if __name__ == '__main__':
36     httpd = make_server('127.0.0.1', 8080, application)
37     print('Serving HTTP on port 8080...')
38     httpd.serve_forever()
簡單web 框架
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8     <style>
 9         h1{
10             background-color: deeppink;
11         }
12     </style>
13 </head>
14 <body>
15     <h1>你好,{{data['name']}}</h1>
16     <h1>我今年:{{data['age']}}歲 </h1>
17     <ul>
18         <li>哈哈哈哈好</li>
19         <li>哈哈哈哈好</li>
20         <li>哈哈哈哈好</li>
21         <li>哈哈哈哈好</li>
22         <li>哈哈哈哈好</li>
23         <li>哈哈哈哈好</li>
24         <li>哈哈哈哈好</li>
25     </ul>
26     <h1>{{data}}</h1>
27 
28     <ul>
29         {%  for k,v in data.items() %}
30             <li>{{k}}:{{v}}</li>
31         {%  endfor    %}
32     </ul>
33 
34 
35 </body>
36 </html>
index.html
 1 import pymysql
 2 
 3 def getUserData():
 4     conn = pymysql.connect(
 5         host='127.0.0.1',
 6         port=3306,
 7         user='root',
 8         password='123456',
 9         database='test',
10         charset='utf8'
11     )
12     try:
13         cursor = conn.cursor(pymysql.cursors.DictCursor)
14         cursor.execute('select * from userinfo limit 2;')
15         ret = cursor.fetchone()
16         conn.commit()
17     except:
18         conn.rollback()
19 
20     cursor.close()
21     conn.close()
22 
23     return ret
op_db.py

 

url 分發: 

正則分組,vue

url 分發 (include  )python

視圖函數 : 

整體上是: FBV (function base view)  和  CBV (class base view)  mysql

 

對FBV  使用 裝飾器 判斷阻攔請求,jquery

 

對CBV 能夠直接在 dispatch() 函數中 判斷阻攔請求 ,也能夠在CBV下寫 裝飾器,不過要藉助 django 的 linux

from django.utils.decorators import method_decorator   

用時: @method_decorator(decwebpack

 1 from django.shortcuts import render,redirect
 2 from django.shortcuts import HttpResponse
 3 
 4 # Create your views here.
 5 from django.views import View
 6 
 7 def home(request):
 8     '''
 9     項目首頁
10     :return:
11     '''
12     if request.method == 'GET':
13 
14         pass
15     elif request.method == 'POST':
16         pass
17 
18 
19     return render(request,'home.html')
20 
21 def app03_home(request):
22     return HttpResponse('這是 app03的首頁')
23 
24 def dec(f):
25     def inner(*args,**kwargs):
26         # 搞事情
27         request = args[0]
28         print(request.META)
29         ua = request.META['HTTP_USER_AGENT']
30         #此時就能夠 根據ua 來判斷了
31         if 'Chrome' in ua:
32             # 合法
33             ret = f(request)
34             return ret
35         else:
36             return HttpResponse("請求不合法")
37 
38     return inner
39 
40 # 加裝飾器 來判斷請求是否合法
41 @dec
42 def login(request):
43     if request.method == 'GET':
44          return render(request, 'login.html')
45     elif request.method == 'POST':
46         username = request.POST.get('username')
47         password = request.POST.get('password')
48         if username == 'zcb' and password == '123':
49             # return HttpResponse('登錄成功') # 跳轉到 登錄成功頁面
50             # print('suc')
51             # return render(request,'login_success.html') # 這種方式  不太好
52             return redirect('/app03/login_success/')
53 
54         else:
55             return HttpResponse('登錄失敗')
56 def login_success(request):
57 
58     return render(request,'login_success.html')
59 
60 
61 from django.utils.decorators import method_decorator
62 # CBV 類的方式 login2
63 class Login2(View):
64     def dispatch(self, request, *args, **kwargs):
65         print('請求來了')
66         # 這裏能夠先 判斷  request 的合法性,若是不合法,就不調用 下面的 方法,
67 
68         ret = super().dispatch(request,*args,**kwargs)
69         print('請求結束了')
70         return ret
71 
72     # @method_decorator(dec)  #CBV 下使用裝飾器
73     def get(self,request):
74         return render(request,'login2.html')
75 
76     def post(self,request):
77         username = request.POST.get('username')
78         password = request.POST.get('password')
79         if username == 'zcb' and password == '123':
80             return redirect('/app03/login_success/')
81         else:
82             return HttpResponse('登錄失敗')
給 login(FBV)和 login2(CBV ) 都加上了 裝飾器 dec

 

request 相關: ios

request.META : ua 等信息都在這, 

request.path_info 

request.path 

request.method

request.GET        --->  .get()  .getlist()

request.POST      --->  .get()  .getlist()

 

 

response 相關: 

HttpResponse 對象 是回覆 字符串,

render() 回覆一個頁面

redirect()  重定向到一個新的頁面,  

模板系統 : 

https://files.cnblogs.com/files/zach0812/django%E6%A8%A1%E6%9D%BF%E7%B3%BB%E7%BB%9F.zip

關於模板渲染你只須要記兩種特殊符號(語法):

  {{ }}和 {% %}

  變量相關的用{{}},邏輯相關的用{%%}。

 

萬能的 點 .  

過濾器( 操做 數據  )| :   

 

 

標籤 (邏輯操做 數據 在 {%  %} 裏操做  ):

 

 

 

 

 

 

模板繼承 

當有重複代碼的時候,使用模板繼承 能夠省不少 代碼,例如 管理的後臺頁面,   

在模板中 加上 {% block % }  槽,  

其餘 文件中 經過    {%   extends 'filename'      % } 來引入模板,  

 

 

組件 化   

 

自定義標籤和過濾器

若是 內置的 標籤(邏輯相關)  和 過濾器(對數據再操做  )  不能知足咱們的需求,能夠自定義,  

在app中建立templatetags模塊(模塊名只能是templatetags)

建立任意 .py 文件,如:my_tags.py

 1 from django import template  # 導入 文件
 2 
 3 register = template.Library() #建立一個註冊器
 4 # register 固定的名字
 5 
 6 
 7 @register.filter
 8 def zz(val,val2=''):  # 自定義 過濾器
 9     # 它的做用是 後面加上  ~    過濾器的參數最多有兩個!!!
10 
11     return val + '~'+val2
12 
13 @register.simple_tag   # 自定義標籤
14 def tt(val,val2,val3):  # 能夠傳多個參數
15     # 它的做用是 後面加上 ~
16     return val + val2+ val3 +'~'
17 
18 
19 # 自定義 組件 標籤  (做用 是 先將 test.html 渲染好以後,直接做爲組件使用)
20 @register.inclusion_tag('test.html')
21 def func(val):
22 
23     data = [11,22,33]
24     data.append(val)
25 
26     return {'data':data}
my_filter_tags.py
1 <div style="background-color: purple;color: #fff;"> 我去 </div>
2 <ul>
3     {% for d in data %}
4         <li>{{ d }}</li>
5     {% endfor %}
6 </ul>
test.html
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     {% load my_filter_tags %}   <!-- 自定義 過濾器(操做數據的 方法 )  -->
11 {#    <h1>歡迎{{ name | zz }} 來到登錄頁面</h1>#}
12     <h1>歡迎{{ name | zz:'~' }} 來到登錄頁面</h1>
13 
14     {% tt name name name %}   <!-- 自定義 標籤 空格 加參數  -->
15     {% func 44 %} <!-- 自定義 組件 標籤   -->
16 
17     <form action="/app03/login/" method="post">
18         {% csrf_token %}
19         用戶名:<input type="text" name="username">
20         密  碼:<input type="text" name="password">
21         <input type="submit">
22     </form>
23 
24 </body>
25 </html>
login.html 這裏是用到自定義標籤 和 過濾器的地方

 

靜態文件:  

把一些  css,js ,jpg .mp4 等文件  加進來, 當服務器請求 這些 .css 等文件的時候,django 就會自動的讀取 發送給瀏覽器, 

引入時:  

 

 

 

ORM --- 單表查詢 : 

 1 from django.db import models
 2 
 3 # Create your models here.
 4 
 5 class Student(models.Model):
 6     # id = models.AutoField(primary_key=True)  # 默認的
 7     name = models.CharField(max_length=16)
 8     age = models.IntegerField()
 9     date = models.DateField(null=True) # 該字段容許 爲空
10 
11 
12 
13     def __str__(self):
14         # 當print (self) 的時候 就會 調用 self.__str__()
15         return self.name
models.py
  1 from django.shortcuts import render,redirect,HttpResponse
  2 
  3 # Create your views here.
  4 from app01 import models # 利用orm 操做數據庫
  5 
  6 def index(request):
  7     #
  8     '''
  9     # 建立 記錄方式1
 10     stu = models.Student(name='tom',age=18)
 11     stu.save()
 12 
 13     # 建立 記錄方式2
 14     # models.Student.objects # 可理解  可經過objects來增刪 改查,
 15     new_obj = models.Student.objects.create(name='e',age=10)
 16     print(new_obj)  # Student object
 17     print(new_obj.name)
 18     print(new_obj.age)
 19     '''
 20 
 21     # 增 ---  批量 插入
 22     '''
 23     objs = []
 24     for i in range(30): # 30個記錄
 25         obj = models.Student(
 26             name = 'tom%s'%i,
 27             age = 10 + i,
 28         )
 29         objs.append(obj)
 30     models.Student.objects.bulk_create(objs) # 速度快  
 31     '''
 32 
 33     # 增 --- update_or_create  有就 更新 無則建立
 34     '''
 35     models.Student.objects.update_or_create(
 36         name='jack', # 若是有 name 的話,就 改 爲下面 的默認值  ,若是沒 的話 ,就建立. 
 37         defaults={
 38             'age':40  
 39         }
 40     )
 41 
 42     '''
 43 
 44 
 45     # 簡單 查詢
 46     '''
 47     # 簡單 查詢之 ---查詢 全部的 數據
 48     all_objs = models.Student.objects.all()
 49     print(all_objs)   # QuerySet 類型 相似列表
 50     for obj in all_objs:
 51         print(obj.name)
 52     # 簡單 查詢之 --- filter 返回的 QuerySet  QuerySet 對象也能夠調用 filter() 
 53     # 條件 查詢 數據 filter() # 查詢失敗 不報錯,返回爲  空。
 54     objs = models.Student.objects.filter(id=8); # id 爲8 的記錄
 55     print(objs)
 56 
 57     # 簡單 查詢之 --- get返回的 model 對象 (Student 對象 )
 58     # 條件 查詢 數據 get() 並且 get() 方法有且只有 一個結果,多了少了  都報錯 。
 59     objs = models.Student.objects.get(id=8);
 60     print(objs)
 61     
 62     '''
 63 
 64     # 刪除 delete
 65     '''
 66     # 經過 stu 對象 來調用刪除
 67     # models.Student.objects.get(id=7).delete() # 須要先把它查出來,而後再刪除
 68 
 69     # 經過 QuerySet 對象  來調用刪除
 70     # models.Student.objects.filter(id=8).delete()
 71 
 72     # models.Student.objects.all().delete()   # 刪除 表中  全部的數據
 73     '''
 74 
 75     # 更新
 76     '''
 77     # stu 對象 不能 update
 78     # models.Student.objects.get(name='jane').update(age = 38)  # stu對象 不能 更新
 79     models.Student.objects.filter(name='jane').update(age = 38) # QuerySet 對象 能夠
 80     '''
 81 
 82     # 更多查詢  都是重點
 83     #01 多條件 查詢,
 84     '''
 85     sets = models.Student.objects.filter(age=38,name='jane')    #條件之間是 and 的關係
 86 
 87     # 關鍵字參數 也能夠傳個 字典~   打散傳參 要注意 ,key value 都要是 字符串,  
 88     # sets = models.Student.objects.filter(**{'age':38,'name':'jane'}) # 也能夠以下格式
 89     print(sets)
 90     
 91     
 92     # 除了 filter()  get 也支持  多條件, 它返回的是  stu 對象 返回結果  有且只能有一個,  
 93     '''
 94 
 95     # 02 排除 exclude , 排除 僅僅是 篩選出來 ,並無刪除原有的數據   # objects  和 queryset對象均可以調用
 96     '''
 97     set = models.Student.objects.exclude(id=9)
 98     print(set) # 返回的是個 QuerySet 對象
 99 
100     set = models.Student.objects.filter(age=38).exclude(id=9) # 先篩選 再 exclude  兩次過濾。
101     print(set)
102     '''
103 
104     #03  排序 orderby  原有數據 沒變
105     '''
106     set = models.Student.objects.all().order_by('age','-id') # 意思是 先按 age 升序 ,而後 按id 降序
107     print(set)   # 默認是升序 ,降序 用 -
108     '''
109     #04 反轉 reverse  # 反轉 必須在 order_by 的基礎上 來 作  。
110     '''
111     set = models.Student.objects.all().order_by('id').reverse()
112     print(set)
113     '''
114 
115     #05 計數 count
116     '''
117     num = models.Student.objects.all().count() # 查詢 以後 結果的 set 的 數量
118     print(num)
119     '''
120 
121     #06 first
122     '''
123     obj = models.Student.objects.all().first() # 返回 結果是 stu 對象
124     print(obj)
125     '''
126 
127     #07 last
128     '''
129     obj = models.Student.objects.all().last()   # 返回 結果是 stu 對象
130     print(obj)
131     '''
132 
133 
134     #08 exist
135     '''
136     # 它 比 直接 if res: 效率高, exist 只要有一個 符合就返回了,
137     flag = models.Student.objects.filter(name='jane').exists() # 返回 bool
138     print(flag)
139     '''
140 
141     #09 values_list 和 values
142     '''
143     set = models.Student.objects.filter(age=38)
144     print(set)
145 
146     set =  models.Student.objects.filter(age=38).values_list() # 把全部 values 變爲元素返回
147     print(set)  # 它照樣是 set 對象, 可是裏面的數據 變爲了 元組,
148 
149     set =  models.Student.objects.filter(age=38).values_list('name','age')
150     print(set)
151 
152     set =  models.Student.objects.filter(age=38).values()
153     print(set) # 裏面變爲 了字典  values_list  和 values 至關於 pymysql 中的 遊標中的 元組 和 字典 ~
154     set =  models.Student.objects.filter(age=38).values('name','age')
155     print(set)
156     '''
157 
158     #10 去重 主要用在 values_list  和 values  後 ;  由於若是是all(),filter() 都包含 id ,而id 是確定不會重複的
159     '''
160     set = models.Student.objects.values_list('age').distinct().count()
161     print(set)
162     '''
163 
164     #11 基於雙下劃線 的模糊查詢  至關於 數據庫 like
165     # set = models.Student.objects.filter(id>20) # 這種寫法是錯誤的, 不支持 大於
166     # 大於
167     set = models.Student.objects.filter( id__gt = 20 ) # 此時id > 20
168     print(set)
169 
170     # 大於等於  gte
171     # 小於 lt
172     # 小於等於 lte
173 
174     # 在... 裏面 in
175     set = models.Student.objects.filter( id__in = [20,22,30] )  # 在 後面三個中的 都要
176     print(set)
177 
178     #range    []  左右 都閉區間
179     set = models.Student.objects.filter(age__range=[18,30])
180     print(set)
181 
182     #包含 contains  該字段 必需要是 字符串
183     set = models.Student.objects.filter(name__contains='tom') #默認區分大小寫
184     print(set)
185 
186     set = models.Student.objects.filter(name__icontains='tom') #i  不區分大小寫
187     print(set)
188 
189     #以 ... 開頭 startswith
190     set = models.Student.objects.filter(name__startswith='ja')
191     print(set)
192 
193     #以 ... 結尾 endswith
194     set = models.Student.objects.filter(name__endswith='e')
195     print(set)
196 
197     # 查詢  與日期相關 比較重要~
198     set = models.Student.objects.filter(date='2000-11-11')
199     print(set)
200     set = models.Student.objects.filter(date__year='2000')
201     print(set)
202     set = models.Student.objects.filter(date__year='2000',date__month='12')
203     print(set)
204     set = models.Student.objects.filter(date__year='2000',date__month='12',date__day='8')
205     print(set)
206     # 查看  大於 2000-12-8
207     set = models.Student.objects.filter(date__year='2000',date__month='12',date__day__gt='8')
208     print(set)
209 
210 
211 
212     return render(request,'index.html')
views.py
  1 """
  2 Django settings for orm_pro project.
  3 
  4 Generated by 'django-admin startproject' using Django 1.11.9.
  5 
  6 For more information on this file, see
  7 https://docs.djangoproject.com/en/1.11/topics/settings/
  8 
  9 For the full list of settings and their values, see
 10 https://docs.djangoproject.com/en/1.11/ref/settings/
 11 """
 12 
 13 import os
 14 
 15 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 17 
 18 
 19 # Quick-start development settings - unsuitable for production
 20 # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
 21 
 22 # SECURITY WARNING: keep the secret key used in production secret!
 23 SECRET_KEY = '9l6_6036bj+*ov$q)yg#p1ny6b8rk(j4z##8+6c)02l2cy@%i3'
 24 
 25 # SECURITY WARNING: don't run with debug turned on in production!
 26 DEBUG = True
 27 
 28 ALLOWED_HOSTS = []
 29 
 30 
 31 # Application definition
 32 
 33 INSTALLED_APPS = [
 34     'django.contrib.admin',
 35     'django.contrib.auth',
 36     'django.contrib.contenttypes',
 37     'django.contrib.sessions',
 38     'django.contrib.messages',
 39     'django.contrib.staticfiles',
 40     'app01.apps.App01Config',
 41 ]
 42 
 43 MIDDLEWARE = [
 44     'django.middleware.security.SecurityMiddleware',
 45     'django.contrib.sessions.middleware.SessionMiddleware',
 46     'django.middleware.common.CommonMiddleware',
 47     'django.middleware.csrf.CsrfViewMiddleware',
 48     'django.contrib.auth.middleware.AuthenticationMiddleware',
 49     'django.contrib.messages.middleware.MessageMiddleware',
 50     'django.middleware.clickjacking.XFrameOptionsMiddleware',
 51 ]
 52 
 53 ROOT_URLCONF = 'orm_pro.urls'
 54 
 55 TEMPLATES = [
 56     {
 57         'BACKEND': 'django.template.backends.django.DjangoTemplates',
 58         'DIRS': [os.path.join(BASE_DIR, 'templates')]
 59         ,
 60         'APP_DIRS': True,
 61         'OPTIONS': {
 62             'context_processors': [
 63                 'django.template.context_processors.debug',
 64                 'django.template.context_processors.request',
 65                 'django.contrib.auth.context_processors.auth',
 66                 'django.contrib.messages.context_processors.messages',
 67             ],
 68         },
 69     },
 70 ]
 71 
 72 WSGI_APPLICATION = 'orm_pro.wsgi.application'
 73 
 74 
 75 # Database
 76 # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
 77 
 78 DATABASES = {
 79     'default': {
 80         'ENGINE': 'django.db.backends.mysql',
 81         'HOST':'127.0.0.1',
 82         'PROT':3306,
 83         'NAME':'orm01',
 84         'USER':'root',
 85         'PASSWORD':'123456',
 86     }
 87 }
 88 
 89 
 90 # Password validation
 91 # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
 92 
 93 AUTH_PASSWORD_VALIDATORS = [
 94     {
 95         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
 96     },
 97     {
 98         'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
 99     },
100     {
101         'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
102     },
103     {
104         'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
105     },
106 ]
107 
108 
109 # Internationalization
110 # https://docs.djangoproject.com/en/1.11/topics/i18n/
111 
112 LANGUAGE_CODE = 'en-us'
113 
114 TIME_ZONE = 'UTC'
115 
116 USE_I18N = True
117 
118 USE_L10N = True
119 
120 USE_TZ = True
121 
122 
123 # Static files (CSS, JavaScript, Images)
124 # https://docs.djangoproject.com/en/1.11/howto/static-files/
125 
126 STATIC_URL = '/static/'
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 # 若是想打印orm轉換過程當中的sql,須要在settings中進行以下配置
139 # LOGGING = {
140 #     'version': 1,
141 #     'disable_existing_loggers': False,
142 #     'handlers': {
143 #         'console':{
144 #             'level':'DEBUG',
145 #             'class':'logging.StreamHandler',
146 #         },
147 #     },
148 #     'loggers': {
149 #         'django.db.backends': {
150 #             'handlers': ['console'],
151 #             'propagate': True,
152 #             'level':'DEBUG',
153 #         },
154 #     }
155 # }
setttings.py

 

修改後端數據 切換頁面   時,能夠經過綁定事件,而後 location.href ,

可是,麻煩,能夠經過 a標籤,它能夠幫咱們自動 發請求, 

django批量操做 models中的表到 admin 中: 

1 from django.contrib import admin
2 
3 # Register your models here.
4 from app01 import models
5 
6 for table in models.__all__: # table 就是個字符串 
7     if hasattr(models,table):
8         admin.site.register(getattr(models,table))
View Code

 

 

django 中 使用外面的腳本 批量導入到數據庫 中數據:(外部文件  操做django 的models  )

 

 1 # 外部 文件使用 djjango 的models, 須要配置 django 環境  (模仿 manage.py )
 2 import os
 3 if __name__ == '__main__':
 4     #===============配置=================
 5     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_pro.settings")
 6     import django
 7     django.setup()
 8     #================================
 9 
10     from app01 import models
11     obj_lists = []
12     for i in range(50):
13         obj = models.Books(
14             name='葵花寶典第%s式'%i,
15             price = 20+i,
16             date ='1980-12-11',
17             press_name= '人民日報出版社'
18         )
19         obj_lists.append(obj)
20 
21     models.Books.objects.bulk_create(obj_lists)
腳本批量導入數據庫數據.py

 

 

url 別名  和 反向解析: 

views.py 中要導入  reverse  

url 路由 的時候 要用name 關鍵字 起個別名,  之後能夠一直用這個別名,

 

 

 

 

起了別名以後,之後,修改 前面的請求路徑 也 不用修改面的,由於用了別名, 

 

html 中 也可使用 url 的別名, 語法: { %   url ' 別名'     %}  ,經常使用在  a標籤 中的 href 屬性中,  

使用別名 的好處是 以防後面升級  路徑時,不用處處更改 路徑,  

 

其中 redirect()中,能夠直接寫 別名,不用 reverse() 也能夠,但,只限於 redirect()  ,  

 

善用別名,

善用路徑,將後端數據放在路徑中,刪除數據 ,編輯數據的時候 ,能夠經過 a 標籤 達到 自動訪問數據庫的目的,例如 /edit/17  意思是編輯 id 爲17 的圖書 ,

後端 數據 不要隨便從 前端中獲取,有多是錯的, 

 

ORM --- 多表 操做  : 

建立 django 的admin 用戶,  

python manager.py createsuperuser 

 

多表操做之 增 刪 改:

 1 from django.db import models
 2 
 3 # Create your models here.
 4 # 做者表
 5 class Author(models.Model):
 6     name = models.CharField(max_length=16)
 7     age = models.IntegerField()
 8     # authorDetail = models.OneToOneField(to='AuthorDetail',to_field='id',on_delete=models.CASCADE) # 不級聯 model.SET_NULL  這時,若是刪了的話,外鍵 就變爲NULL了
 9     authorDetail_id = models.OneToOneField(to='AuthorDetail') # 默認 to_field 是id ,  django1.x 版本默認是 級聯
10     def __str__(self):
11         return self.name
12 
13 
14 
15 # 做者詳情表  # 做者表 和 做者詳情表 是一對一的 關係
16 class AuthorDetail(models.Model):
17     birthday = models.DateField()
18     tele = models.CharField(max_length=32)
19     addr = models.CharField(max_length=64)
20 
21     def __str__(self):
22         return self.addr
23 
24 
25 
26 # 出版社 表
27 class Press(models.Model):
28     name = models.CharField(max_length=32)
29     city = models.CharField(max_length=32)
30     email = models.EmailField() #實際也是 CharField,不過它能夠幫咱們 校驗  是不是郵箱
31 
32     def __str__(self):
33         return self.name
34 
35 
36 
37 #書籍表  和 做者是多對多的關係
38 #書籍表 和 出版社 這裏認爲是一對多關係 (一個出版社 出版多本書 )
39 class Book(models.Model):
40     title = models.CharField(max_length=32)
41     publishDate = models.DateField()
42     price = models.FloatField()
43     # price = models.DecimalField(max_digits=5,decimal_places=2) # 5位整數,2位小數
44 
45     press_id = models.ForeignKey(to='Press',on_delete=models.CASCADE) # 關聯到 出版社 表 ,
46 
47     author = models.ManyToManyField(to='Author') #不是真實的字段,能夠經過它操做第三張表 ,它 只是自動幫咱們建立第三張表(  下面的  )
48 
49     def __str__(self):
50         return self.title
51 
52 # class BookToAuthor(models.Model):   # 多對多的關係 用第三張  表
53 #     book_id = models.ForeignKey(to='Book')
54 #     author_id = models.ForeignKey(to='Author')
models.py
 1 """orm_pro URL Configuration
 2 
 3 The `urlpatterns` list routes URLs to views. For more information please see:
 4     https://docs.djangoproject.com/en/1.11/topics/http/urls/
 5 Examples:
 6 Function views
 7     1. Add an import:  from my_app import views
 8     2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
 9 Class-based views
10     1. Add an import:  from other_app.views import Home
11     2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13     1. Import the include() function: from django.conf.urls import url, include
14     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
15 """
16 from django.conf.urls import url
17 from django.contrib import admin
18 
19 from app01 import views
20 urlpatterns = [
21     url(r'^admin/', admin.site.urls),
22 
23 
24     url(r'^query/',views.query)
25 
26 ]
urls.py
  1 from django.shortcuts import render,redirect,HttpResponse
  2 
  3 # Create your views here.
  4 from app01 import models # 利用orm 操做數據庫
  5 from django.urls import reverse  # 能夠反向解析 url 的別名
  6 
  7 def query(request):
  8 #一對一 操做多表 操做 author 表 和 authordetail表
  9     # 增  (一種是 對象 一種是屬性 )
 10     '''
 11     author_detail_obj =  models.AuthorDetail.objects.create(
 12         birthday='1998-10-10',
 13         tele='188888888889',
 14         addr='黑龍江哈爾濱'
 15     )
 16     # 添加方式1  用屬性 =  類對象的方式
 17     models.Author.objects.create(
 18         name='m萬濤',
 19         age = 40,
 20         authorDetail_id=author_detail_obj # 這是類的屬性
 21     )
 22     '''
 23     '''
 24     # 經常使用 
 25     # 添加方式2  用 表字段 =  查詢結果 方式
 26     obj = models.AuthorDetail.objects.filter(addr='山西臨汾').first()
 27     # print(obj.id)
 28 
 29     models.Author.objects.create(
 30         name='m狗蛋',
 31         age=24,
 32         authorDetail_id_id = obj.id  # 這是 數據庫表中的 字段
 33     )
 34     '''
 35     #
 36     '''
 37     models.AuthorDetail.objects.get(id=1).delete()  #刪它 會刪 author ,而後會刪 author_book 表 -->  牽一髮而動全身
 38     '''
 39     #
 40     # models.Author.objects.get() # 不能用get 它獲得的對象是 author 沒有update()
 41     '''
 42     models.Author.objects.filter(id=2).update(
 43         name='德剛2',
 44         age=38,
 45         authorDetail_id_id = 6,
 46         # authorDetail_id = models.AuthorDetail.objects.get(id=6)
 47     )
 48     '''
 49 
 50     #
 51 
 52 # 一對多 操做多表  press 和 book  是一對多的關係  一本書 只能 由一個出版社
 53     #
 54     '''
 55     models.Book.objects.create(
 56         title = '李剛的辛福生活',
 57         publishDate='2009-10-10',
 58         price= 121,
 59         # press_id= models.Press.objects.create(name='幸福出版社',city='北京',email='1001@xx.com'),
 60         # press_id= models.Press.objects.get(id=1),
 61         
 62         # 經常使用 
 63         # press_id_id= models.Press.objects.get(id=1).id,
 64         press_id_id = 1  # 外鍵的時候, 這四種方式均可以   
 65     )
 66     '''
 67 
 68 
 69     # 刪  和一對一的刪除同樣,
 70     # models.Press.objects.get(id=1).delete()
 71 
 72     #
 73     '''
 74     models.Book.objects.filter(id=8).update(
 75         title='鋼鐵之翼2',
 76         # press_id_id =2,
 77         press_id = models.Press.objects.get(id=2)
 78     )
 79     '''
 80 
 81     #
 82 
 83 # 多對多 操做多表  author  和 book 表
 84     #
 85     '''
 86     # 經常使用
 87     book_obj = models.Book.objects.get(id=1)
 88     # book_obj.author  # 使用 Book 中的author 屬性來添加多對於的記錄
 89     book_obj.author.add(*[1,2]) # book_id 1  的author 有兩個 1 和 2
 90     # book_obj.author.add(*[1, 2,3])  # book_id 1  的author 有三個 1,2,3
 91     '''
 92 
 93     '''
 94     # 先找到 兩個做者
 95     author1 = models.Author.objects.get(id=1)
 96     author2 = models.Author.objects.get(id=2)
 97     # 找到 書
 98     book_obj = models.Book.objects.get(id=3)
 99     book_obj.author.add(*[author1,author2])
100     '''
101 
102     # 刪 就是刪除第三張 表
103     '''
104     # 首先要找到 這個表 ,經過 Book 中的 author 屬性
105     book_obj = models.Book.objects.get(id=9)
106     # book_obj.author.remove(3) # remove 寫的是對應的 author id
107     book_obj.author.remove(*[3,5]) #刪的是 9 對應的 3,5
108 
109     # book_obj.author.clear()  # 刪的是 book 9 對應的全部 author
110     # book_obj.author.set('4') # 將id book 9 對應的author id修改成 4 設置爲1個
111     # book_obj.author.set(['2','3']) # 將id book 9 對應的author id修改成 4和 6  設置爲多個
112     '''
113     #
114     '''
115     多對多的 更改 就是 上面 刪除中的 set   
116     '''
117 
118     #
119 
120     return  HttpResponse('ok ')
121     pass
views.py

 

級聯的時候,orm   沒有   級聯更新,有級聯刪除,  

多表操做之 查:

多表查詢,不管是 基於 對象 仍是基於雙下劃線,它們都有  正向查詢 和 反向查詢 ,  

就看外鍵那個屬性寫在哪,從  有 外鍵的表 查 叫:正向 , 反之,反向查詢,   

 

 

1,基於對象 的跨表 查詢 (相似於    子查詢  )

 

 

2,基於雙下劃線的 跨表查詢 (相似於連表   join 鏈接  )

 

related_name關鍵字: 

related_name = ‘xx’ :當建立外鍵 的時候 。它的做用是 當反向查詢的時候 不用表名了,用 xx就好了。  

 

聚合 函數使用    : 

from django.db.models import Avg,Max,Min,Sum,Count

補充:‘12’.isdigit( ) 很差,它全識別,使用  '12'.isdecimal()

 

分組 查詢  : 

group by  分組 就是爲了 統計信息,

以及 分組後的   having 

 

F查詢   和  Q查詢 : 

 

 

 

orm (mysql)的坑(orm 不能解決):

分組致使的,  分組以後取 其餘字段 會致使數據有問題,

 

若是分組,select 只能 select groupby 後的字段  和  統計的結果,其餘字段都是無心義的,  

只有以下能夠:

 

 

若是是實在想要其餘字段,orm 解決不了 了,  

原生sql 能夠解決:

先不分組, 先鏈接,鏈接以後,首先按照 price 降序排列,使得價格最大的在第一行,(這樣就避免了後面 分組時候的錯誤),

鏈接以後:

 

先按price 降序排序:以下:

 

而後,若是 max() 取數據,其餘數據也都是在第一行的,就不會有錯了, 

最終以下:

1 select title,price from 
2     (
3     select app01_author.id,app01_book.title,app01_book.price from app01_author 
4     INNER JOIN app01_book_author on app01_author.id=app01_book_author.author_id 
5     INNER JOIN app01_book on app01_book.id=app01_book_author.book_id 
6     ORDER BY app01_book.price desc
7     ) as b  
8     GROUP BY id
View Code 

注:sql_mode 很是重要,  

 1 """orm_pro URL Configuration
 2 
 3 The `urlpatterns` list routes URLs to views. For more information please see:
 4     https://docs.djangoproject.com/en/1.11/topics/http/urls/
 5 Examples:
 6 Function views
 7     1. Add an import:  from my_app import views
 8     2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
 9 Class-based views
10     1. Add an import:  from other_app.views import Home
11     2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13     1. Import the include() function: from django.conf.urls import url, include
14     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
15 """
16 from django.conf.urls import url
17 from django.contrib import admin
18 
19 from app01 import views
20 urlpatterns = [
21     url(r'^admin/', admin.site.urls),
22 
23     url(r'^query/',views.query)
24 
25 ]
urls.py
 1 from django.db import models
 2 
 3 # Create your models here.
 4 # 做者表
 5 class Author(models.Model):
 6     name = models.CharField(max_length=16)
 7     age = models.IntegerField()
 8     # authorDetail = models.OneToOneField(to='AuthorDetail',to_field='id',on_delete=models.CASCADE) # 不級聯 model.SET_NULL  這時,若是刪了的話,外鍵 就變爲NULL了
 9     authorDetail_id = models.OneToOneField(to='AuthorDetail') # 默認 to_field 是id ,  django1.x 版本默認是 級聯
10     def __str__(self):
11         return self.name
12 
13 
14 
15 # 做者詳情表  # 做者表 和 做者詳情表 是一對一的 關係
16 class AuthorDetail(models.Model):
17     birthday = models.DateField()
18     tele = models.CharField(max_length=32)
19     addr = models.CharField(max_length=64)
20 
21     def __str__(self):
22         return self.addr
23 
24 
25 
26 # 出版社 表
27 class Press(models.Model):
28     name = models.CharField(max_length=32)
29     city = models.CharField(max_length=32)
30     email = models.EmailField() #實際也是 CharField,不過它能夠幫咱們 校驗  是不是郵箱
31 
32     def __str__(self):
33         return self.name
34 
35 
36 
37 #書籍表  和 做者是多對多的關係
38 #書籍表 和 出版社 這裏認爲是一對多關係 (一個出版社 出版多本書 )
39 class Book(models.Model):
40     title = models.CharField(max_length=32)
41     publishDate = models.DateField()
42     dianzan_num = models.IntegerField(default=0) # 點贊
43     comment_num = models.IntegerField(default=0) # 評論  後面又加上的(要麼 default= ,要麼set_null = True),
44 
45     price = models.FloatField()
46     # price = models.DecimalField(max_digits=5,decimal_places=2) # 5位整數,2位小數
47 
48                                                                 # related_name = 'xx' 的意思是 反向查詢的時候,不用表名了,用xx便可,
49     # press_id = models.ForeignKey(to='Press',on_delete=models.CASCADE,related_name='xx') # 關聯到 出版社 表 ,
50     press_id = models.ForeignKey(to='Press',on_delete=models.CASCADE) # 關聯到 出版社 表 ,
51 
52     author = models.ManyToManyField(to='Author') #不是真實的字段,能夠經過它操做第三張表 ,它 只是自動幫咱們建立第三張表(  下面的  )
53 
54     def __str__(self):
55         return self.title
56 
57 # class BookToAuthor(models.Model):   # 多對多的關係 用第三張  表
58 #     book_id = models.ForeignKey(to='Book')
59 #     author_id = models.ForeignKey(to='Author')
models.py
  1 from django.shortcuts import render,redirect,HttpResponse
  2 
  3 # Create your views here.
  4 from app01 import models # 利用orm 操做數據庫
  5 from django.urls import reverse  # 能夠反向解析 url 的別名
  6 
  7 def query(request):
  8 #1 基於對象的 多表查詢  (相似於 子查詢)
  9 #一對一 操做多表 操做 author 表 和 authordetail表
 10     #
 11     # 正向 查詢
 12     '''
 13     author_obj = models.Author.objects.filter(name='超哥').first()
 14     print(author_obj.authorDetail_id.birthday)
 15     print(author_obj.authorDetail_id.tele)
 16     print(author_obj.authorDetail_id.addr)
 17     '''
 18     # 反向 查詢  經過authorDetail 中 數據 查詢 author 的信息
 19     '''
 20     detail_obj = models.AuthorDetail.objects.get(addr='江西南昌')
 21     # 具體是 經過小寫的 表名
 22     print(detail_obj.author.name)
 23     print(detail_obj.author.age)
 24     print(detail_obj.author.authorDetail_id)
 25     '''
 26 
 27 # 一對多 操做多表  press 和 book  是一對多的關係  一本書 只能 由一個出版社
 28     #
 29     # 正向查詢
 30     '''
 31     book_obj = models.Book.objects.get(id=7)
 32     print(book_obj.press_id.name)
 33     print(book_obj.press_id.city)
 34     print(book_obj.press_id.email)
 35     '''
 36     # 反向查詢
 37     '''
 38     press_obj = models.Press.objects.get(name='幸福出版社')
 39     # 具體是用  表名_set
 40     # print(press_obj.book_set.first().title)
 41     # print(press_obj.book_set.first().publishDate)
 42     # print(press_obj.book_set.first().price)
 43     # print(press_obj.book_set.first().press_id)
 44     for book in press_obj.book_set.all():
 45         print(book.title)
 46         print(book.publishDate)
 47         print(book.price)
 48         print(book.press_id )
 49     '''
 50 
 51 # 多對多 操做多表  author  和 book 表
 52     #
 53     # 正向查詢 一本書 是 哪幾個做者寫的
 54     '''
 55     book_obj = models.Book.objects.get(id=9)
 56     # 經過 book 中的 author 屬性
 57     print(book_obj.author.all()) #<QuerySet [<Author: 德剛2>, <Author: 超哥>]>
 58     '''
 59 
 60     # 反向查詢 一個做者 寫了  哪幾本書
 61     '''
 62     author_obj = models.Author.objects.get(name='德剛2')
 63     print(author_obj.book_set.all())
 64     '''
 65 
 66 #2 基於 雙下劃綫 的 多表查詢  (相似於 join 鏈接)
 67 #一對一 操做多表 操做 author 表 和 authordetail表
 68     # 查 m狗蛋的地址
 69     '''
 70     # 正向查詢
 71     # authorDetail_id   __   addr 它是先將 author 和 authorDeatail 鏈接在一塊兒,而後再查 addr
 72     set = models.Author.objects.filter(name='m狗蛋').values('authorDetail_id__addr','age')
 73     print(set)  # 查找 addr 時 連表
 74     # 經過使用小寫的 表名
 75     # 反向查詢
 76     set = models.AuthorDetail.objects.filter(author__name='m狗蛋').values('addr','author__age')
 77     print(set) # 查找 addr 前 連表
 78     '''
 79 
 80     # 查 地址爲 江西南昌 做者的名字
 81     '''
 82     # 正向查詢
 83     set = models.Author.objects.filter(authorDetail_id__addr='江西南昌').values('name','authorDetail_id__birthday')
 84     print(set)
 85     # 反向查詢
 86     set = models.AuthorDetail.objects.filter(addr='江西南昌').values('author__name','tele')
 87     print(set)
 88     '''
 89     # 查 電話 爲 222222222 的做者的 名字
 90     '''
 91     # 正向查詢
 92     set = models.Author.objects.filter(authorDetail_id__tele='222222222').values('name')
 93     print(set)
 94     # 反向查詢
 95     set = models.AuthorDetail.objects.filter(tele='222222222').values('author__name')
 96     print(set)
 97     '''
 98 
 99 # 一對多 操做多表  press 和 book  是一對多的關係  一本書 只能 由一個出版社
100     # 查 李剛的辛福生活 書  的出版社 是哪一個?
101     '''
102     # 正向查詢 有外鍵的 用外鍵 鏈接, 無外鍵的 用 表名小寫鏈接,
103     set = models.Book.objects.filter(title='李剛的辛福生活').values('press_id__name')
104     print(set)
105     # 反向查詢
106     set = models.Press.objects.filter(book__title='李剛的辛福生活').values('name')
107     print(set)
108     '''
109     # 查 b哥出版社 都出版了 哪些書
110     '''
111     # 正向查詢
112     set = models.Book.objects.filter(press_id__name='b哥出版社').values('title')
113     print(set)
114     # 反向查詢
115     set = models.Press.objects.filter(name='b哥出版社').values('book__title')
116     print(set)
117     '''
118 
119 
120 # 多對多 操做多表  author  和 book 表
121     # 查 李剛的辛福生活  是誰寫的
122     '''
123     # 正向查詢
124     set = models.Book.objects.filter(title='李剛的辛福生活').values('author__name')
125     print(set)
126     # 反向查詢
127     set = models.Author.objects.filter(book__title='李剛的辛福生活').values('name')
128     print(set)
129     '''
130 
131     # 查 m狗蛋 寫了 哪些書
132     '''
133     # 正向查詢
134     set = models.Book.objects.filter(author__name='m狗蛋').values('title')
135     print(set)
136     # 反向查詢
137     set = models.Author.objects.filter(name='m狗蛋').values('book__title')
138     print(set)
139     '''
140 #3 基於 雙下劃綫 的 進階查詢
141     # 查 b哥出版社 , 出版的書 的名稱 以及做者的名稱 # press author -->  press --book --author
142     # 三張表
143     # 推薦第一種
144     '''
145     set = models.Press.objects.filter(name='b哥出版社').values('book__title','book__author__name')
146     print(set)
147 
148     set = models.Book.objects.filter(press_id__name='b哥出版社').values('title','author__name')
149     print(set)
150 
151     set = models.Author.objects.filter(book__press_id__name='b哥出版社').values('book__title','name')
152     print(set)
153     '''
154 
155 
156     # 聚合 函數
157     '''
158     from django.db.models import Avg,Max,Min,Sum,Count
159     # 算全部書  的平均價格
160     # price = models.Book.objects.all().aggregate(Avg('price'))  # aggregate() 返回的是個字典
161     res = models.Book.objects.all().aggregate(a = Avg('price'))  # a 會覆蓋默認的鍵
162     print(res)
163 
164     res = models.Book.objects.all().aggregate(Max('price'),Sum('price'),Count('price'))
165     print(res)
166     '''
167 
168     # 分組查詢
169     from django.db.models import Avg,Min,Max,Count,Sum
170     # 一種寫法
171     '''
172     # 查 每一個出版社 出版書籍 的平均價格  若是用 sql的話: select avg(price) from app01_book group by press_id_id;
173     #models.Book.objects.values('press_id_id') #全部出版社的id, 它做爲 後面 annotate 時候的  分組條件,
174     # models.Book.objects.values('press_id_id').annotate() # 分組
175     ret = models.Book.objects.values('press_id_id').annotate(a = Avg('price'),b = Min('price'),c=Max('price'),d=Avg('press_id_id') )
176     print(ret)
177 
178     # 多個 條件分組 
179     # 以 press_id_id 和 id 爲分組條件
180     # models.Book.objects.values('press_id_id','id')
181 
182     ret = models.Book.objects.values('press_id_id','id').annotate(a = Avg('price'))
183     print(ret)
184     print(ret.filter(a__gt=25)) # 在查出 的結果中再次篩選, 它至關於 having ,group by 以後的 having  
185     '''
186 
187 
188     #另外一種寫法 以press 表爲 分組依據,
189     '''
190     # 上面是把  values() 放在了 annotate ()前面 很差理解,
191     # models.Press.objects  # Press 就是分組條件
192                                           # a 必定要寫
193     # ret = models.Press.objects.annotate(a = Avg('xx__price')) # xx  是book 的別名, 作了一次鏈接,
194     # print(ret) #<QuerySet [<Press: b哥出版社>, <Press: yy出版社>]>
195     ret = models.Press.objects.annotate(a = Avg('xx__price')).values('a') # 同時會將 a 塞到 press 這個表中作爲一個字段,
196     print(ret)
197     '''
198 
199 
200     # F 函數   和 Q函數
201 
202     # F 查詢:主要用於 單表中的 字段 的 比較,
203     from django.db.models import F , Q
204     # 例如查詢 book 表中 評論數 大於   點贊贊 書
205     '''
206     ret = models.Book.objects.filter(comment_num__gt=F('dianzan_num'))
207     print(ret)
208     '''
209 
210     # F函數 還支持 四則運算
211     '''
212     ret = models.Book.objects.filter(comment_num__gt=F('dianzan_num') + 10)
213     print(ret)
214     '''
215     # F 函數的 其餘用途
216     '''
217     # 讓 book 全部書 的價格 都加 20
218     models.Book.objects.all().update(price =F('price') + 20)
219     '''
220 
221 
222     # Q函數  一個表中 的 字段 之間的或者關係,
223     '''
224     # 查 評論數  大於20 而且 點贊數 大於 20
225     ret = models.Book.objects.filter(comment_num__gt=20,dianzan_num__gt=20)
226     print(ret)
227 
228     # 查 評論數  大於20  或者  點贊數 大於 20
229     ret = models.Book.objects.filter(Q(comment_num__gt=20)|Q(dianzan_num__gt=20))
230     print(ret)
231     # Q 也支持  & ~
232     ret = models.Book.objects.filter(~(Q(comment_num__gt=20)&Q(dianzan_num__gt=20)))
233     print(ret)
234 
235     # Q 也支持嵌套   把 多個條件 括起來,
236     ret = models.Book.objects.filter(Q(~(Q(comment_num__gt=20) & Q(dianzan_num__gt=20)))&Q(price__gt=141))
237     print(ret)
238     '''
239 
240 
241     # 習題 (orm mysql 的坑):
242     # 查詢 每一個做者出版 書的最高價格
243     ret = models.Author.objects.annotate(m = Max('book__price')).values('m')
244     print(ret)
245     # 它對應的原生 sql 是:
246     ''' 
247     # 鏈接    
248     # select * from app01_author 
249     inner join app01_book_author on app01_author.id = app01_book_author.author_id 
250     inner join app01_book on app01_book.id = app01_book_author.book_id;  
251 
252     # select  app01_author.id, max(app01_book.price) from app01_author 
253     inner join app01_book_author on app01_author.id = app01_book_author.author_id 
254     inner join app01_book on app01_book.id = app01_book_author.book_id
255     group by app01_author.id;
256 
257 
258     '''
259     # 上面尚未 坑,
260     # 下面就是 orm 的坑: 分組致使的坑~
261 
262     #查 每一個做者出版的全部書的最高價格  以及  最高價格的那本書的名稱
263     ret =  models.Author.objects.annotate( m = Max('book__price')).values('m','book__title')
264     print(ret)
265     # 若是寫 確定是上面這樣寫, 它是有坑的,
266 
267     '''
268     | id | name    | age | authorDetail_id_id | id | book_id | author_id | id | title                 | publishDate | price | press_id_id | comment_num | dianzan_num |
269     +----+---------+-----+--------------------+----+---------+-----------+----+-----------------------+-------------+-------+-------------+-------------+-------------+
270     |  2 | 德剛2   |  38 |                  6 |  8 |       3 |         2 |  3 | 鋼鐵之翼              | 2020-03-06  |    40 |           2 |          10 |         100 |
271     |  2 | 德剛2   |  38 |                  6 | 27 |       9 |         2 |  9 | 得當的心裏獨白        | 2008-10-01  |   220 |           5 |          10 |          40 |
272     若是數據如上面, max(price),  price字段獲得 的是 220 ,可是,其餘字段 就沒辦法取了,只能按照第一行的數據。這 orm 是沒法解決的。  
273     
274     mysql  中 能夠設置 sql_mode = only_full_group_by ,此時就不能 select * 了,只能 select group by 後的字段 以及統計數據,其餘字段沒法拿到, 
275     
276     
277     總結:  分組以後 拿統計數據纔是 有意義的,其餘字段 沒有任何意義 ~       
278     '''
279 
280     '''
281     # 上述問題,orm 不能解決, 原生sql 能夠解決:  
282     #select title,price from 
283     (
284     select app01_author.id,app01_book.title,app01_book.price from app01_author 
285     INNER JOIN app01_book_author on app01_author.id=app01_book_author.author_id 
286     INNER JOIN app01_book on app01_book.id=app01_book_author.book_id 
287     ORDER BY app01_book.price desc
288     ) as b  
289     GROUP BY id
290     '''
291 
292 
293 
294 
295     return  HttpResponse('ok ')
views.py

 

django 中時間相關: 

 

auto_now 是更新的時候,自動更新時間,  auto_now_add 是建立的時候 加時間,更新時不更新時間,  

並且差8小時, 配置: USE_TZ = False  

 

問題: 

auto_now_add 沒多大問題,auto_now 更新數據的時會有問題, 

咱們若是用update() 去更新數據,auto_now 是不會幫咱們更新時間的,【咱們能夠本身傳入時間 datetime.datetime.now() 手動增長 】(經常使用)


若是用 obj.name = 'tom3' obj.save() 更新數據時,auto_now 會幫更新時間

 

 

時間轉化:

https://www.cnblogs.com/clschao/articles/10757374.html

 

 

 

 

 

ORM --- 鎖 和 事務: 

https://www.cnblogs.com/clschao/articles/10463267.html

行級鎖:

select_for_update,   

共享鎖, 排他鎖,

表鎖: 

 

 

事務四大特性:

原子性 , 一致性,持久性,隔離性=  。

 

Django --- Ajax : 

https://www.cnblogs.com/clschao/articles/10468335.html  

ajax 是js的技術, 

這裏再也不使用 form 和 a  標籤來 發送請求了,它是使用 ajax 發送請求,請求結果也是會返回給 ajax 的請求,  

 

先後端 分離的時候用的就是 ajax , js 中的 ajax 就是相似於 python 中的 request , 

登錄認證 只是 ajax 的一個應用,  

 

 

補:content-type  :

它是先後端 交互的時候的消息格式, 

django 默認解析的 content-type 是   urlencoded 

 

 

 

若是你發送請求 使用 content-type :application /json 那麼,django 就不會幫你解析參數了,須要你本身手動從 請求頭中本身  解析, 

在作接口的時候,可能會遇到此類問題, 

 

django 還認:  multipart/form-data  上傳文件(見下面)   用的,django 只認這兩種 content-type , 

 

上傳文件:  

兩種: 1,form 表單 上傳文件, 2,ajax 上傳文件, 

 

 

 

如何將Python 中的 時間日期類型 進行 序列化:

python中的datetime等時間日期類型是不能進行json序列化的,由於json沒有對應的格式,此時須要咱們本身手動處理:

 1 import json
 2 from datetime import datetime
 3 from datetime import date
 4 
 5 #對含有日期格式數據的json數據進行轉換
 6 class JsonCustomEncoder(json.JSONEncoder):
 7     def default(self, field):
 8         if isinstance(field,datetime):
 9             return field.strftime('%Y-%m-%d %H:%M:%S')
10         elif isinstance(field,date):
11             return field.strftime('%Y-%m-%d')
12         else:
13             return json.JSONEncoder.default(self,field)
14 
15 
16 d1 = datetime.now()
17 
18 dd = json.dumps(d1,cls=JsonCustomEncoder) # 使用的時候,要用cls 關鍵字 來指定自定義的類,  
19 print(dd)

 

 1 {% load static %}
 2 <!DOCTYPE html>
 3 <html lang="zh-CN">
 4 <head>
 5     <meta charset="utf-8">
 6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 7     <meta name="viewport" content="width=device-width, initial-scale=1">
 8     <title>hello world</title>
 9 
10 </head>
11 <body>
12     <h1>上傳文件 </h1>
13 
14     <form action="" method="post" enctype="multipart/form-data">
15         {% csrf_token %}
16         頭像:<input type="file" name="head_pic">
17         用戶名:<input type="text" name="username">
18         <input type="submit">
19     </form>
20 </body>
21 </html>
upload.html
 1 {% load static %}
 2 <!DOCTYPE html>
 3 <html lang="zh-CN">
 4 <head>
 5     <meta charset="utf-8">
 6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 7     <meta name="viewport" content="width=device-width, initial-scale=1">
 8     <title>hello world</title>
 9 </head>
10 <body>
11     <h1>上傳文件2</h1>
12     文件:<input type="file" id="file">  {#    ajax  上傳 不須要 name 屬性也可 ajax 須要咱們本身寫 key value  #}
13 
14     用戶名:<input type="text" id="uname">
15     <button id="btn">上傳</button>
16     <script src="{% static 'jquery.js' %}"></script>
17     <script>
18         $('#btn').click(function () {
19             // console.log($('#file')[0].files[0]);
20             var form_data = new FormData();
21             form_data.append('uname',$('#uname').val());
22             form_data.append('file_obj',$('#file')[0].files[0]);
23             form_data.append('csrfmiddlewaretoken','{{ csrf_token }}');
24 
25             $.ajax({
26                 url:'{% url 'upload2' %}',
27                 type:'post',
28                 {#data:{#}
29                 {#    csrfmiddlewaretoken:'{{ csrf_token }}',#}
30                 {#    uname:$('#uname').val(),#}
31                 {#    //file_obj: $('#file')[0].files[0]  // 直接上傳 不能夠,ajax 上傳數據 需藉助formdata#}
32 {##}
33 {#                }#}
34                 data:form_data,
35                 processData:false, // 不處理數據
36                 contentType:false, // 不設置內容類型   在ajax 上傳文件時候 必須寫
37 
38 
39                 success:function (res) {
40                     console.log(res);
41                 }
42 
43             })
44 
45         });
46 
47 
48 
49     </script>
50 </body>
51 </html>
upload2.html
  1 from django.shortcuts import render,redirect,HttpResponse
  2 
  3 
  4 # Create your views here.
  5 from app01 import models # 利用orm 操做數據庫
  6 from django.urls import reverse  # 能夠反向解析 url 的別名
  7 from django.http import JsonResponse  # 作的工做是 添加 content-type: application/json
  8 
  9 def query(request):
 10     return  HttpResponse('ok ')
 11 
 12 from django.views import View
 13 
 14 def index(request):
 15     return render(request,'index.html')
 16 
 17 def home(request):
 18     if request.method == 'GET':
 19         all_books = models.Book.objects.all()
 20         print(all_books)
 21 
 22         all_press = models.Press.objects.all()
 23 
 24         return render(request,'home.html',{'all_books':all_books,'all_press':all_press})
 25     else:
 26         print(request.POST)
 27 
 28         return HttpResponse('ok')
 29 
 30 
 31 def data(request):
 32     ll = [11,1,1,33,44]
 33         # 在回覆 非字典的時候,要加上 safe = False
 34     return JsonResponse(ll,safe = False)
 35 
 36 # 經過form 表單上傳文件
 37 def upload(request):
 38     if request.method == 'GET':
 39         return render(request,'upload.html')
 40     else:
 41         print(request.POST) #<QueryDict: {'csrfmiddlewaretoken': ['Tu0Eo0hBDKlvmAS8ynxo8iEY2IY0smCiR9QQbDeFe9HGsRPmQNtMyNE4ZS2EKb9u'], 'head_pic': ['10.jpg'], 'username': ['zcb']}>
 42         print(request.FILES) # POST 中放的只是 文件名字,真實的數據 在 request.FILES  中,可是 form 表單中要加: enctype = 'multipart/form-data'
 43             # 配置好  enctype 中 以後: <MultiValueDict: {'head_pic': [<InMemoryUploadedFile: 9.jpg (image/jpeg)>]}>
 44         # 保存到 服務器
 45         file_obj = request.FILES.get('head_pic') # file_obj 能夠當作是 文件句柄
 46         f_name = file_obj.name
 47 
 48         from orm_pro import settings
 49         import os
 50         path = os.path.join(settings.BASE_DIR,'static_files','user_img',f_name)
 51         with open(path,"wb") as f:
 52             # 方式1: 數據是多行的,
 53             for i in file_obj:
 54                 f.write(i)
 55 
 56             # 方式2 :若是數據就只有一行
 57             # for i in file_obj.chunks(): # 仍是讀數據,默認一次 讀 64KB ( 只是django 中 )
 58             #     f.write(i)
 59 
 60 
 61         return HttpResponse('ok')
 62 
 63 # 經過 ajax 上傳文件
 64 def upload2(request):
 65     if request.method == 'GET':
 66         print('hhhhhh')
 67         return render(request,'upload2.html')
 68         # return render(request,'upload2.html')
 69     else:
 70         print('#================================')
 71         print(request.POST)
 72         print(request.FILES)
 73         file_obj = request.FILES.get('file_obj')
 74 
 75         with open(file_obj.name, "wb") as f:
 76             # 方式1: 數據是多行的,
 77             for i in file_obj:
 78                 f.write(i)
 79             # 方式2 chunks()
 80 
 81 
 82         print('#================================')
 83 
 84         return HttpResponse('ok')
 85 
 86 
 87 
 88 import json
 89 class LoginView(View):
 90     def get(self,request):
 91         return render(request,'login.html')
 92 
 93     def post(self,request):
 94         # 此時是 ajax 請求過來的 再也不是 form 了
 95         uname = request.POST.get('uname')
 96         pwd = request.POST.get('pwd')
 97         if uname == 'zcb' and pwd == '123':
 98             print("成功")
 99             # return render(request,'index.html') # ajango  成功以後 返回個首頁
100             ret = {'code':0,'msg':'ok','url':'/index/'}
101             return HttpResponse(json.dumps(ret))
102             # return HttpResponse(json.dumps(ret),content_type='application/json') # content_type這樣以後,ajax收到數據就不用反序列化了
103             # 上面一行 還要手動本身寫 content_type ,有沒有不用本身寫的,有,   JsonResponse() # from django.http import JsonResponse
104                 #直接 return JsonResponse(ret)
105         else:
106             # return  redirect('/login/') 此時 ajax 不認識 django 的 redirect 的,要想重定向要經過js 的location.href 。
107 
108             # 應該返回的是 redirect 的url
109             ret = {'code':3,'msg':'用戶名或密碼錯誤','url':'/login/'}
110             # 要返回的應該是 str
111             return HttpResponse(json.dumps(ret))
views.py
 1 """orm_pro URL Configuration
 2 
 3 The `urlpatterns` list routes URLs to views. For more information please see:
 4     https://docs.djangoproject.com/en/1.11/topics/http/urls/
 5 Examples:
 6 Function views
 7     1. Add an import:  from my_app import views
 8     2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
 9 Class-based views
10     1. Add an import:  from other_app.views import Home
11     2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
12 Including another URLconf
13     1. Import the include() function: from django.conf.urls import url, include
14     2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
15 """
16 from django.conf.urls import url
17 from django.contrib import admin
18 
19 from app01 import views
20 urlpatterns = [
21     url(r'^admin/', admin.site.urls),
22     url(r'^query/',views.query),
23     url(r'^index/',views.index),
24     url(r'^home/', views.home,name='home'),
25     url(r'^data/', views.data,name='data'),
26     url(r'^upload/$',views.upload,name='upload'),
27     url(r'^upload2/$',views.upload2,name='upload2'),
28     url(r'^login/', views.LoginView.as_view(),name='login'),
29 
30 
31 ]
urls.py
 1 {% load static %}
 2 <!DOCTYPE html>
 3 <html lang="zh-CN">
 4 <head>
 5     <meta charset="utf-8">
 6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 7     <meta name="viewport" content="width=device-width, initial-scale=1">
 8     <title>hello world</title>
 9     
10 </head>
11 <body>
12     <h1>你好,世界!</h1>
13     <ul>
14     </ul>
15     <script src="{% static 'jquery.js' %}"></script>
16     <script>
17         $.ajax({
18             url:'{% url 'data' %}',
19             type:'get',
20             success:function (res) {
21                 console.log(res);
22                 $.each(res,function (k,v) {
23                     console.log(k,v);
24                     /*
25                     //1
26                     var li = document.createElement('li');
27                     $(li).text(v);
28                     $('ul').append(li);
29                     */
30                     //2
31                     var s = '<li>'+v.toString()+'</li>';
32                     $('ul').append(s);
33                 })
34 
35             }
36         })
37 
38 
39     </script>
40 
41 </body>
42 </html>
home.html

上傳文件:  https://files.cnblogs.com/files/zach0812/django_%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6.zip

 

django--- cookie 和 session(會話): 

http  是不支持持續會話的,

http的兩個特性:

1,無鏈接 (發一次  收一次 , 完事兒~)   

2,無狀態  (本次鏈接 結束,下次鏈接時 不認識對方,), cookie (給http 請求頭中加了 cookie )來解決 這個問題,

 

 

 

 

 

cookie 是服務端 發來存儲在瀏覽器上的 一組鍵值對, 

 

 

 

 

 

爲何會有 session  :

 

 

把以前 想發給客戶端的 放在 服務端,只給 客戶端 發個key ,

如今就是不能直接看到 真實cookie 的真實鍵值對了,並且存儲在服務端, 用戶下次訪問 要拿着 key 過來訪問服務端,  

django 中設置session 再也不經過 響應對象 來設置了,直接經過request 來設置, 

並且django 設置 session 時,會保存到 數據庫  django 的內置表  django_session 。  

 

 

取 加密的cookie 時, 

 

 

 

注: 通過網絡傳輸 ,只有 str 一種類型,因此,直接  使用  cookie 時,True  是 str 類型, 若是使用了 session 的話,True 仍是 bool 類型,   

 

 

這個服務端的加密數據,是根據 用戶 和瀏覽器 來生成的 記錄, 

django 作的事情是:一個瀏覽器 和一個用戶 只給保留一條記錄(覆蓋), (可是,若是沒有session_id(用戶主動清除cookie) ,仍是會產生新的記錄的,無法判斷是不是 原來的 瀏覽器  和  用戶了  )

 

cookie 和 session 裏的參數 :  

set_cookie() 的參數: 

 

 

 

request.session 的一些方法:  

 

 

views.py 中的 視圖函數:

 

 

 

 

補: django 項目的 配置文件

from django.conf import global_settings  ,能夠在 global_settings  配置 key  ,不叫 session_id ,

 

 

可是,直接在用戶配置文件中 配置便可, 

 

django--- 中間件  (midware): 

以前給視圖函數加裝飾器來判斷是用戶是否登陸,把沒有登陸的用戶請求跳轉到登陸頁面。

咱們經過給幾個特定視圖函數加裝飾器實現了這個需求。可是之後添加的視圖函數可能也須要加上裝飾器,這樣是否是稍微有點繁瑣。

咱們就能夠用更適宜的方式來實現相似給全部請求都作相同操做的功能了,就是中間件(就是一個類),

咱們在一個固定位置 寫個py 文件便可,

 

 

 

 

 把這個配置到 settings.py 便可, 這樣全部的請求都會通過咱們的這個 process_request()  ,響應走的時候(必須 return response )都會通過 process_response() ,

 

 

中間件的一個用途:限制IP 頻率, (客戶端的 ip 在 request.META 中 ),規則: 例如,10s 以內 只能訪問三次,  

 

Django 請求的生命週期:

 

 

 

Django -- form 驗證 組件  :

https://www.cnblogs.com/clschao/articles/10486468.html

先後端 的認證 都是須要的, 

form組件 主要作  數據校驗,  

views.py :  

 

name  只能 6 到  16 位,  

在使用的時候,能夠將loginForm 對象 渲染到 HTML 中,

若是使用 form_obj.as_p  會自動 加 label ,label 能夠指定 input 的名字, 可是擴展性很差,通常不用 .as_p    

 

django form 表單上傳文件:

參考: https://www.cnblogs.com/clschao/articles/10468335.html#part_2 

models.py   中  ImageField(upload)

def test(request):
    if request.method == 'GET':
        test_form = TestForm(request)
        return render(request,'zcb.html',{'test_form':test_form})
    else:
        img_obj = request.FILES.get('img')
        file_name = img_obj.name

        with open('static/xxnaicha/img/'+file_name,'wb') as f:
            for chunks in img_obj.chunks():
                f.write(chunks)

        return HttpResponse('ok')
View Code

 

 

 

 

 

Django Rest_Framework 組件 : 

具體詳細項目見 百度網盤,

drf 序列化: 

當前端 向服務器請求數據,咱們手工 序列化數據很麻煩,尤爲當涉及外鍵關係,須要咱們本身自行構建數據結構,

Django自帶的序列化組件,很差(外鍵關係沒法處理),from django.core.serializers import serialize

建議使用:  drf( Django Rest_Framework )

 

APIView csrf 豁免,發送post 請求 比View方便,  

 

 

 

 

1 # 構建一個 序列化器
2 class BookSerialize(serializers.Serializer):
3     id = serializers.IntegerField()
4     title = serializers.CharField(max_length=32)
5     CHOICES = ((1,'python'),(2,'linux'))
6     # course = serializers.ChoiceField(choices=CHOICES) # 直接這樣寫  拿到的數據是 前面的 1,2  
7     course = serializers.CharField(source='get_course_display') # source 能夠執行 一些orm 操做,這時拿到的是 後面的Python 和 linux
source 屬性執行 orm 操做

 

 1 from rest_framework.views import APIView
 2 from rest_framework import serializers
 3 from rest_framework.response import Response
 4 
 5 class AuthorSerialize(serializers.Serializer):
 6     id = serializers.IntegerField()
 7     name = serializers.CharField(max_length=32)  # 想要什麼字段寫什麼,寫什麼就序列化什麼  
 8 
 9 class PublishSerialize(serializers.Serializer):
10     id = serializers.IntegerField()
11     name = serializers.CharField(max_length=32)
12 
13 class BookSerialize(serializers.Serializer):
14     id = serializers.IntegerField()
15     title = serializers.CharField(max_length=32)
16 
17     publish = PublishSerialize()  # 由於一本書只有一個出版社,
18     author = AuthorSerialize(many=True) #由於一本書可能有多個做者 因此 many = True
19 
20 class Index(APIView):
21     def get(self,request):
22         book_queryset = Book.objects.all()
23         ser_obj = BookSerialize(book_queryset,many=True)
24         return Response(ser_obj.data)
drf 序列化解決 外鍵關係

 

注: 還要把 rest_framework 註冊進 settings 裏, 以下: 

 

drf  反序列化: 

當前端 提交過來一個數據的時候,咱們就須要 反序列化了, 

假設前端傳過來的數據以下:

 

 1 from rest_framework.views import APIView
 2 from rest_framework import serializers
 3 from rest_framework.response import Response
 4 
 5 class AuthorSerialize(serializers.Serializer):
 6     id = serializers.IntegerField()
 7     name = serializers.CharField(max_length=32)  # 想要什麼字段寫什麼,寫什麼就序列化什麼
 8 
 9 class PublishSerialize(serializers.Serializer):
10     id = serializers.IntegerField()
11     name = serializers.CharField(max_length=32)
12 
13 class BookSerialize(serializers.Serializer):
14     id = serializers.IntegerField(required=False) #required=False 表示  id不用校驗
15     title = serializers.CharField(max_length=32)
16     CHOICES = ((1,'PYTHON'),(2,'LINUX'))
17     course = serializers.CharField(source='get_course_display',write_only=True) # 序列化時候 用 ,這是返回字符
18     post_course = serializers.ChoiceField(choices=CHOICES,read_only=True) # 反序列化時候 用 ,前端提交過來 數字
19 
20     publish = PublishSerialize(write_only=True)
21     author = AuthorSerialize(many=True,write_only=True)
22 
23     post_publish_id = serializers.IntegerField (read_only=True)
24     post_author_id = serializers.ListField(read_only=True)
25 
26     def create(self, validated_data):
27         #  post 提交數據時,orm 操做保存數據
28         book_obj = models.Book.create(
29             title=validated_data['title'],
30             publish_id = validated_data['post_publish_id'],
31             course = validated_data['post_course']
32         )
33         # 處理多對多的關係
34         book_obj.authors.add(*validated_data['post_author_id'])
35         return book_obj  # 必定要 return
36 
37 
38 
39 class Index(APIView):
40     def get(self,request):
41         book_queryset = models.Book.objects.all()
42         ser_obj = BookSerialize(book_queryset,many=True)
43         return Response(ser_obj.data)
44 
45     def post(self,request):
46         book_obj = request.data # 至關於 原來 request.POST  data中放着除了 GET外的信息  (APIView 封裝了下原先的request 並獲得了新的request)
47 
48         # 對前端傳來的數據 作校驗
49         ser_obj = BookSerialize(data=book_obj)
50         if ser_obj.is_valid():
51             ser_obj.save()
52             return Response(ser_obj.data)
53         else:
54             return Response(ser_obj.errors)
加上 反序列化(前端向後端提交數據)

 

全部的視圖類,  

 

drf    版本控制組件 認證組件  權限控制  頻率控制   分頁器  解析器 渲染器     :  

項目見 百度網盤

解析器: 

django 中默認content-type 只支持兩種 類型,一個是form-data 一個是url-encode 

 

 

 

 

 

渲染器: 

 

 

 

 

 

 

 

 

 

RESTful 規範:  

REST 風格: 表述性狀態轉移,【這個風格只是個建議,】

URI:統一資源標識符,

URL:統一資源定位符, (url 是經過定位實現的URI )

統一資源接口: 

  根據HTTP請求方式的不一樣對資源進行不一樣的操做(get 獲取,post新增),
例如:在先後端交互時,不能再addbook,editbook,delbook ,應該直接一個book ,而後根據不一樣的請求方式 來作不一樣的邏輯(get獲取,post新增,delete刪除)
  遵循HTTP請求方式的語義(get 就是獲取,post就是新增(不能不增),)

 

遵循 REST風格的就叫 RESTful 規範

 

 

 

django ContentType組件:  

使用ContentType 的好處:  

 

使用ContentType 的步驟: 

1,優惠券表中 須要foreignkey 到 ContentType
2,object_id 是所關聯到的表的 id
3,GenericForeignKey 二者, 使用對象.就能夠直接 找到所要的記錄

 

 

https://www.cnblogs.com/GGGG-XXXX/articles/9697458.html

 

接口測試 Postman:  

 

開發流程:  

功能結構圖
原型圖
根據功能需求設計表結構( 沒有表結構 ER圖 ,是 不能夠寫代碼的 )

 

先後端分離項目 文檔十分重要, 

 

 

 

數據庫設計軟件PowerDesigner :

xxx

權限:

經過url 來控制 用戶的訪問,

 

權限表結構設計 (rbac): 

rbac 模式 :role based access control :基於角色 的 權限控制,    

 

 

動態菜單 展現     : 

不一樣的用戶 展現 不一樣的菜單欄,  

 

 

ES6 經常使用語法 :

筆記參看:https://github.com/able8/hello-es6#12promise

變量的定義:

var 會有  變量的提高,

let 不會有 變量的提高,並且不能重複定義

 1         // var 變量提高,能夠重複定義  
 2         var a = 'tom';
 3         var a = 'jane';
 4         console.log(a);
 5 
 6         // let 不會變量提高,也不能重複定義,更嚴格
 7         let b = 'tom' ;
 8         let b = 'ajen'; // 報錯 duplicate declaration # 重複定義
 9         console.log(b);
10         
11         // const 固定值,不能修改,是常量  

模板字符串:

用`(反引號)標識,用${}將變量括起來

1 let n = 'tom';
2 let age = 18;
3 let motto = `hello world,my name is ${n},my age is ${age}`;
4 console.log(motto);

箭頭函數 (匿名函數):

python 中的匿名函數爲 : lambda   

1 // res => res + 1  
2 let f = res => res + 1  ; 
3 let ret = f(1);
4 console.log(ret);  
基本箭頭函數

 

this:

普通函數   的this 指的是 當前函數 最近的調用者, 

箭頭函數的this 與它所處的上下文中的this一致(經常使用於回調),

 1 function f() {
 2     console.log(this);
 3 }
 4 f(); //this 爲 Window對象
 5 let obj = {
 6     func:f
 7 };
 8 obj.func(); //this 爲 obj 這個對象
 9 
10 let obj2 = {
11     test:obj
12 };
13 obj2.test.func();// this仍然是 obj 這個對象 
普通函數中,this爲它最近的調用者
 1 function f() {
 2     setTimeout(function () {
 3         console.log('普通函數');
 4         console.log(this);// 爲它的最近調用者 即 window 
 5         console.log('普通函數');
 6     });
 7     setTimeout(res=>{
 8         console.log('匿名函數');
 9         console.log(this); // 和 它所處的上下文 環境中this一致 ,即 f函數中的 this 一致  
10         console.log('匿名函數');
11     });
12 }
13 let obj = {
14     func:f
15 };
16 obj.func();
普通函數 和 箭頭函數中this 的區別

 

箭頭函數的好處:

若是回調函數是普通函數,想使用 外層函數的this, 必需要在外層先 let that = this; ,而後使用that , 

而若是是箭頭函數,則能夠直接使用this ,

數據的打散  和 聚合  :

Python 函數實參位置  中用*  打散列表,** 打散字典,

Python 函數形位置  中用*  聚合列表 ,**  聚合字典,  

 

es 6 中也有相似操做: ...   

三個點在實參位置時,起到聚合成數組  的做用,  

1 function f(a,b,...args) {
2     console.log(a);
3     console.log(b);
4     console.log(args);
5 }
6 f(1,2,3,4,5); // 3,4,5,被聚合成一個數組 
三個點在形參位置 --聚合做用

三個點在實參位置時,起到打散數組  的做用,  

1 function f(a,b,c) {
2     console.log(a);
3     console.log(b);
4     console.log(c);
5 }
6 f(...[1,2,3]); // 把[1,2,3] 打散成 1,2,3
三個點在實參位置 --打散做用

 

解構 賦值:

es 6 中也有相似操做: 

它是用{} 解析對象, 用 [ ] 解析數組,  

View Code

ES6的 面向對象  :

在es5中,定義一個類是 用原型鏈 來定義,es6 中,咱們能夠經過class 來定義類了~

 1 /*類的基本用法*/
 2 class Demo{
 3     constructor(userName,age){
 4         this.nick = userName;
 5         this.age = age;
 6     }
 7     run(){
 8         console.log('run with ',this.nick);
 9         return 1;
10     }
11 }
12 let d = new Demo('tom',18);
13 console.log(d.nick,d.age);
14 let ret = d.run();
15 console.log('我是 方法run 的返回值: ',ret);
16 
17 /*繼承*/
18 class MyDemo extends Demo{
19     constructor(userName,age) {
20         super(userName,age);  // 子類中沒有this ,須要先super下,
21         this.nick = userName;
22         this.age = age;
23     }
24 }
25 let demo2 = new MyDemo('a',18);
26 demo2.run();
View Code

 

ES6 中的 import 和 export  :

與python 不一樣的是,js中要想import 導入,必需要先 export 出 變量,

要想導入,必須先拋出 變量,  

可是,瀏覽器還不支持它們,還不能識別,  

 

 

ES6的 Promise  :

使用js進行異步操做,會陷入回調地獄(callback hell ) ,代碼可讀性下降,  

 1 /*
 2 * Promise 實例化: 要傳它一個函數
 3 * 爲了後續使用,這個函數要有兩個參數(不須要咱們手動傳入,js引擎傳),第一個表明是成功要執行的函數,第二個是失敗要執行的函數
 4 *
 5 * */
 6 
 7 let p = new Promise(function (a,b) {
 8     //這裏寫 異步代碼
 9     $.ajax({
10         url:'test.py',
11         success:function (res) {
12             console.log(res);
13             a();
14             // b();
15         },
16         error:function(res){
17             console.log('fail');
18         }
19     })
20 });
21 // 此時默認上面的異步代碼必定執行成功
22 p.then(function f1() {
23     console.log('上面Promise 形參中的第一個函數 a執行了');
24 },function f2() {
25     console.log('上面Promise 形參中的第二個函數 b執行了');
26 });
27 
28 p.then(function f1() {
29     console.log('上面Promise 形參中的第一個函數 a執行了');
30 }).catch(function f2() {
31     console.log('上面Promise 形參中的第二個函數 b執行了');
32 })
Promise 簡單使用--構建Promise對象,以及 Promise對象.then() 和 Promise對象.then().catch()

上面代碼若是不用Promise對象的話,代碼以下:

 1 function test() {
 2     $.ajax({
 3         url:'test.py',
 4         success:function (res) {
 5             console.log(res);
 6             function f1() {
 7                 console.log('上面Promise 形參中的第一個函數 a執行了');
 8             }
 9             f1();
10         },
11         error:function(res){
12             console.log('fail');
13             function f2() {
14                 console.log('上面Promise 形參中的第二個函數 b執行了');
15             }
16             f2();
17         }
18     })
19 }
20 test();
不用Promise 的話,可讀性低,

 

再如:

若是是有兩次異步請求:  

 1 let p = new Promise(function (a,b) {
 2     //這裏寫 異步代碼
 3     $.ajax({
 4         url:'test.py',
 5         success:function (res) {
 6             console.log(res);
 7             a();
 8         },
 9         error:function(res){
10             console.log('fail');
11             b();
12         }
13     })
14 });
15 
16 let p2 = new Promise(function (a,b) {
17     $.ajax({
18         url:'test2.py',
19         success:function (res) {
20             a();
21         },
22         error:function (res) {
23             b();
24         }
25     })
26 });
27 
28 p.then(function f1() {
29     p2.then(function f3() {
30         console.log('2次都成功了');
31     }).catch(function f4() {
32         console.log('第一次成功,第二次失敗');
33     })
34 },function f2() {
35     p2.then(function f3() {
36         console.log('第一次失敗,第二次成功');
37     }).catch(function f4() {
38         console.log('2次都失敗了');
39     })
40 });
使用Promise ,異步請求邏輯邏輯清晰

若是不用Promise實現上述代碼: 

 1 function test() {
 2     $.ajax({
 3         url:'test.py',
 4         success:function (res) {
 5             function f1() {
 6                 $.ajax({
 7                     url:'test.py',
 8                     success:function () {
 9                         console.log('2次都成功了');
10                     },
11                     error:function () {
12                         console.log('第一次成功,第二次失敗');
13                     }
14                 })
15             }
16             f1();
17         },
18         error:function(res){
19             console.log('fail');
20             function f2() {
21                 $.ajax({
22                     url:'test.py',
23                     success:function () {
24                         console.log('第一次失敗,第二次成功');
25                     },
26                     error:function () {
27                         console.log('2次都失敗了');
28                     }
29                 })
30             }
31             f2();
32         }
33     })
34 }
35 test();
可讀性查,回調地獄

 

批量操做Promise對象:

除了上面一個一個Promise 對象的用,還有多個Promise對象一塊兒使用的,  

Promise.all() 和 Promise.race()  

 1 let p = new Promise(function (a,b) {
 2     //這裏寫 異步代碼
 3     $.ajax({
 4         url:'test1.py',
 5         success:function (res) {
 6             a();
 7         },
 8         error:function(res){
 9             b();
10         }
11     })
12 });
13 
14 let p2 = new Promise(function (a,b) {
15     $.ajax({
16         url:'test1.py',
17         success:function (res) {
18             a();
19         },
20         error:function (res) {
21             b();
22         }
23     })
24 });
25 
26 // 一個一個的使用 仍是麻煩 垃圾
27 // p.then(function f1() {
28 //     p2.then(function f3() {
29 //         console.log('2次都成功了');
30 //     }).catch(function f4() {
31 //         console.log('第一次成功,第二次失敗');
32 //     })
33 // },function f2() {
34 //     p2.then(function f3() {
35 //         console.log('第一次失敗,第二次成功');
36 //     }).catch(function f4() {
37 //         console.log('2次都失敗了');
38 //     })
39 // });
40 
41 // 批量的用 all 是所有執行成功
42 // race 是看誰執行的快
43 Promise.all([p,p2]).then(function f() {
44     console.log('兩次都成功了');
45 }).catch(function () {
46     console.log('不是兩個都成功,一個失敗,或兩個都失敗了');
47 });
48 
49 Promise.race([p,p2]).then(function f() {
50     console.log('有一個已經執行完了');
51 }).catch(function f() {
52     console.log('所有失敗');
53 });
批量操做Promise

 

 1 let p = new Promise(function (a,b) {
 2     //這裏寫 異步代碼
 3     $.ajax({
 4         url:'test3.py',
 5         success:function (res) {
 6             a(res);
 7         },
 8         error:function(res){
 9             b(res);
10         }
11     })
12 });
13 
14 let p2 = new Promise(function (a,b) {
15     $.ajax({
16         url:'test2.py',
17         success:function (res) {
18             a(res);
19         },
20         error:function (res) {
21             b(res);
22         }
23     })
24 });
25 
26 // 批量的用 all 是所有執行成功
27 // race 是看誰執行的快,若是在比賽中發現有一個已經失敗,失敗
28 Promise.all([p,p2]).then(function f(res) {
29     // console.log(res);//  [data1 ,data2] 重要
30     console.log('兩次都成功了');
31 }).catch(function (res) {
32     // console.log(res);// 第一個失敗的 數據
33     console.log('不是兩個都成功,一個失敗,或兩個都失敗了');
34 });
35 
36 Promise.race([p,p2]).then(function f(res) {
37     console.log(res); // 第一個執行完的 數據  重要
38     console.log('有一個已經執行完了');
39 }).catch(function f(res) {
40     console.log(res);// 第一個檢測到的那個,失敗的那個的數據
41     console.log('檢測有一個失敗,或所有失敗');
42 });
all() 和 race() 中的傳參問題

 

封裝函數 用於生成Promise對象:

咱們發現 Promise對象以後url 不一樣,所以能夠封裝一個函數 專門用來生成Promise對象: 

 1 function get_promise(url){
 2     return new Promise(function (a,b) {
 3         $.ajax({
 4             url:url,
 5             success:function (res) {
 6                 a(res);
 7             },
 8             error:function (res) {
 9                 b(res);
10             }
11         })
12     })
13 }
14 let p = get_promise('test.py');
15 let p2 = get_promise('test2.py');
16 
17 Promise.all([p,p2]).then(function (res) {
18     console.log('兩次都成功了');
19     console.log('第一個數據');
20     console.log(res[0]);
21     console.log('第二個數據');
22     console.log(res[1]);
23 })
封裝一個用於生成Promise對象的函數
 1 // function get_promise(url){
 2 //     return new Promise(function (a,b) {
 3 //         $.ajax({
 4 //             url:url,
 5 //             success:function (res) {
 6 //                 a(res);
 7 //             },
 8 //             error:function (res) {
 9 //                 b(res);
10 //             }
11 //         })
12 //     })
13 // }
14 function get_promise(url){
15     return new Promise((a,b)=>{
16         $.ajax({
17             url:url,
18             success:res=>{
19                 a(res);
20             },
21             error:res=>{
22                 b(res);
23             }
24         })
25     })
26 }
27 
28 let p = get_promise('test.py');
29 let p2 = get_promise('test2.py');
30 
31 Promise.all([p,p2]).then(function (res) {
32     console.log('兩次都成功了');
33     console.log('第一個數據');
34     console.log(res[0]);
35     console.log('第二個數據');
36     console.log(res[1]);
37 })
再用上箭頭函數,更好一點,更簡潔

 

 1 function get_promise(url){
 2     return new Promise((a,b)=>{
 3         /*
 4         $.ajax({
 5             url:url,
 6             success:res=>{
 7                 a(res);
 8             },
 9             error:res=>{
10                 b(res);
11             }
12         })*/
13         // 這裏寫異步代碼 
14     })
15 }

注:上面的a, b形參名字,通常咱們用 resolve 和 reject 來表示   

ES8 :

ES8 的 async 和 await :

 1     function block(sec) {
 2         while(1){
 3             if(new Date().getSeconds() === sec){
 4                 break;
 5             }
 6         }
 7     }
 8     function getData(url){
 9         // block(15); //模擬 正在 從url 獲取數據  ...
10         return 'success';
11     }
12 
13     async function test() {
14         return (await getData('test.py'));
15     }
16     let p = test();
17     p.then(function (res) {
18         console.log(res);
19     });
20     console.log('hello world1');
21 /*
22 * function前面加上async關鍵字,表示該function須要執行異步代碼。
23 * async function函數體內可使用await關鍵字,且await關鍵字只能出如今async function函數體內。
24 * await關鍵字能夠跟在任意變量或者表達式以前,await後面 的將會是個異步過程
25 *
26 * 1,若是沒有 async 內沒有使用 await ,那麼,將會是同步過程
27 * 2,若是 async 中使用了 await
28 *      第一個await 時,此時阻塞兩個地方一個是主程序,一個是第一個await 後的代碼
29 *      而後 第一個await 後代碼執行完畢後,而後執行 主程序,最後再執行 第一個await後的代碼 30 * */

vue 框架:

前端回顧:

vue 的思想: 數據來驅動視圖,  它改變 了原先 獲取dom 渲染dom 的思想

 

後端有MVC(django 中的MTV 模式  ),M - M , V - T ,C - V

前端呢,又基於MVC 改進成了 MVVM ,Model ,  View, VIewModel ,

MVVM中的   VM  和 C  和 django 中的 v(視圖層函數)功能一致:都是給view提供處理好的數據的,  

vue 的 經常使用指令 :  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box">
11         {{name}}
12         {{motto}}
13     </div>
14     <script src="vue.js"></script>
15     <script>
16         const app = new Vue({
17             el:'.box', // 1,指定 vue 的做用域
18             data:{     // 2,放入數據
19                 name:'tom',
20                 motto:'Life is short , I learn Python!'
21             }
22         })
23     </script>
24 </body>
25 </html>
vue的簡單使用

v-text  和 v-html :  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box">
11         {{name}}
12         <div v-text="motto"></div>
13         <div v-html="hobby"></div>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         const app = new Vue({
18             el:'.box', // 1,指定 vue 的做用域
19             data:{     // 2,放入數據
20                 name:'tom',
21                 motto:'Life is short , I learn Python!',
22                 hobby:`<ul>
23                             <li>學習</li>
24                             <li>遊戲</li>
25                             <li>電影</li>
26                         </ul>`
27             }
28         })
29     </script>
30 </body>
31 </html>
View Code

v-if:  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <div v-if="age > 18 ">你已經成年了</div>
12         <div v-else-if="age < 18 ">你還未成年</div>
13         <div v-else>你恰好18</div>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         const app = new Vue({
18             el:'.box', // 1,指定 vue 的做用域
19             data:{     // 2,放入數據
20                 age:22
21             },
22             methods:{
23 
24             }
25         })
26     </script>
27 </body>
28 </html>
View Code

它底層是 經過控制 appendChild 來實現的,不會一次性將全部標籤都放到頁面,哪一個條件成立,顯示誰。

 

v-show : 

v-show 是經過style 中的display 來控制的,  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <div v-show="isShow">Hello world</div>
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         const app = new Vue({
16             el:'.box', // 1,指定 vue 的做用域
17             data:{     // 2,放入數據
18                 isShow:true
19             },
20             methods:{
21 
22             }
23         })
24     </script>
25 </body>
26 </html>
View Code

 

v-for:  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box">
11         <ul>
12             <li v-for="(course,index) in course_lists" :key="index">{{course}}{{index}}</li>
13         </ul>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         const app = new Vue({
18             el:'.box', // 1,指定 vue 的做用域
19             data:{     // 2,放入數據
20                 course_lists:['python','django','flask']
21             }
22         })
23     </script>
24 </body>
25 </html>
View Code

 

 

v-bind:   

動態綁定屬性

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box">
11         <img v-bind:src="url" alt="">
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         const app = new Vue({
16             el:'.box', // 1,指定 vue 的做用域
17             data:{     // 2,放入數據
18                 url:'https://www.baidu.com/img/baidu_jgylogo3.gif'
19             }
20         })
21     </script>
22 </body>
23 </html>
View Code

簡寫:  冒號 :  

 

v-on:

v-on:click   

簡寫:@click  

綁定事件,   

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <button v-on:click="myClick('tom')">Come on</button>
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         const app = new Vue({
16             el:'.box', // 1,指定 vue 的做用域
17             data:{     // 2,放入數據
18             },
19             methods:{
20                 myClick:function(arg){
21                     console.log('我是 ',arg);
22                 }
23             }
24         })
25     </script>
26 </body>
27 </html>
View Code

@mouseenter  

@mouseleave  等等...  

 

當綁定多個事件的時候,以下:

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <button v-on="{mouseenter:enter,mouseleave:leave}">Come on</button>
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         const app = new Vue({
16             el:'.box', // 1,指定 vue 的做用域
17             data:{     // 2,放入數據
18             },
19             methods:{
20                 enter:function () {
21                     console.log('進入');
22                 },
23                 leave:function () {
24                     console.log('離開');
25                 }
26 
27             }
28         })
29     </script>
30 </body>
31 </html>
View Code

 

v-model: 

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <input type="text" v-model="username">
12         {{username}}
13 
14         <textarea name="" id="" cols="30" rows="10" v-model="article"></textarea>
15         {{article}}
16 
17         <select name="" id="" v-model="choices">
18             <option value="0">aaa</option>
19             <option value="1">bbb</option>
20             <option value="2">ccc</option>
21         </select>
22         {{choices}}
23         <select name="" id="" v-model="choices2" multiple>
24             <option value="0">aaa</option>
25             <option value="1">bbb</option>
26             <option value="2">ccc</option>
27         </select>
28         {{choices2}}
29     </div>
30     <script src="vue.js"></script>
31     <script>
32         const app = new Vue({
33             el:'.box', // 1,指定 vue 的做用域
34             data:{     // 2,放入數據
35                 username:'',
36                 article:'',
37                 choices:'',
38                 choices2:[],
39             },
40             methods:{
41 
42             }
43         })
44     </script>
45 </body>
46 </html>
實時渲染

 

指令修飾符:  

若是想失去光標的時候,再渲染,能夠用 點 給指令加上小的功能,  

這裏使用 

.lazy   

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <input type="text" v-model.lazy="username">
12         {{username}}
13     </div>
14     <script src="vue.js"></script>
15     <script>
16         const app = new Vue({
17             el:'.box', // 1,指定 vue 的做用域
18             data:{     // 2,放入數據
19                 username:'',
20             },
21             methods:{
22 
23             }
24         })
25     </script>
26 </body>
27 </html>
View Code

 

.number :轉爲number 類型,

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11 <!--        <input type="text" v-model="price">-->
12 <!--        {{ typeof price}}-->
13 
14 <!--        可是數據庫中但願是  number 類型-->
15         <input type="text" v-model.lazy.number="price">
16         {{ typeof price}}
17         <pre>    i love you</pre>
18     </div>
19     <script src="vue.js"></script>
20     <script>
21         const app = new Vue({
22             el:'.box', // 1,指定 vue 的做用域
23             data:{     // 2,放入數據
24                 price:''
25             },
26             methods:{
27 
28             }
29         })
30     </script>
31 </body>
32 </html>
View Code

 

補充:HTML中的 pre 標籤 能夠打印數據的原始狀態, 多個空格也能展現出來, 

.trim: 

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <input type="text" v-model.trim="motto">
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         const app = new Vue({
16             el:'.box', // 1,指定 vue 的做用域
17             data:{     // 2,放入數據
18                 motto:''
19             },
20             methods:{
21             }
22         })
23     </script>
24 </body>
25 </html>
此時,用戶輸入的內容若是 左右帶有空格,都會被去掉

 

自定義指令:  :  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <div v-my="d">
12             我是div 標籤
13         </div>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         Vue.directive('my',function (arg1,arg2) {
18             console.log(arg1); // 指令操做的對象
19             console.log(arg2); // 相關的數據對象
20             if(arg2.value){
21                 arg1.style.border = '1px solid red';
22             }
23         });
24         const app = new Vue({
25             el:'.box', // 1,指定 vue 的做用域
26             data:{     // 2,放入數據
27                 d:true
28             },
29             methods:{
30             }
31         })
32     </script>
33 </body>
34 </html>
View Code

再加上 指令修飾符:

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <div v-my.flag1.flag2="d">
12             我是div 標籤
13         </div>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         Vue.directive('my',function (arg1,arg2) {
18             console.log(arg1); // 指令操做的對象
19             console.log(arg2); // 相關的數據對象
20             if(arg2.value){
21                 arg1.style.border = '1px solid red';
22                 if(arg2.modifiers.flag1 && arg2.modifiers.flag1){
23                     arg1.style.backgroundColor = 'purple'; 
24                 }
25             }
26         });
27         const app = new Vue({
28             el:'.box', // 1,指定 vue 的做用域
29             data:{     // 2,放入數據
30                 d:true
31             },
32             methods:{
33             }
34         })
35     </script>
36 </body>
37 </html>
View Code

vue DOM 相關 :

 

獲取dom:

 

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <div ref="div1">div1</div>  <!-- 必定要是 ref  -->
12         <div ref="div2">div2</div>
13         <button @click="clickEvt">點我啊</button>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         const app = new Vue({
18             el:'.box', // 1,指定 vue 的做用域
19             data:{     // 2,放入數據
20             },
21             methods:{
22                 clickEvt:function () {
23                     // 這裏的this 是 app
24                     // this.$refs.div1.style.backgroundColor='red';
25                     this.$refs.div2.style.backgroundColor='red';
26                 }
27             }
28         })
29     </script>
30 </body>
31 </html>
經過this.$.refs 來獲取dom

 

計算屬性:  

它和 data 的區別是:它一般放一些動態的數據,   

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <table>
12             <thead>
13                 <tr>
14                     <th>科目</th>
15                     <th>成績</th>
16                 </tr>
17             </thead>
18             <tbody>
19                 <tr>
20                     <td>語文</td>
21                     <td><input type="text" v-model.number="c"></td>
22                 </tr>
23                 <tr>
24                     <td>數學</td>
25                     <td><input type="text" v-model.number="m"></td>
26                 </tr>
27                 <tr>
28                     <td>英語</td>
29                     <td><input type="text" v-model.number="e"></td>
30                 </tr>
31                 <tr>
32                     <td>總分</td>
33                     <td>{{c+m+e}}</td>
34                 </tr>
35                 <tr>
36                     <td>平均分</td>
37                     <td>{{(c+m+e)/3}}</td>
38                 </tr>
39             </tbody>
40         </table>
41     </div>
42 
43     <script src="vue.js"></script>
44     <script>
45         const app = new Vue({
46             el:'.box', // 1,指定 vue 的做用域
47             data:{     // 2,放入數據
48                 c:'',
49                 m:'',
50                 e:''
51             },
52             methods:{
53             }
54         })
55     </script>
56 </body>
57 </html>
計算 總分 和 平均分

可是,有的時候,咱們不但願在 模板中使用大量的邏輯,這時,就可使用 計算屬性, 

 

數據的監聽:  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         {{name}}
12         <br>
13         {{arr}}
14         <br>
15         {{obj}}
16     </div>
17 
18     <script src="vue.js"></script>
19     <script>
20         const app = new Vue({
21             el:'.box', // 1,指定 vue 的做用域
22             data:{     // 2,放入數據
23                 name:'tom',
24                 arr:[1,2,3],
25                 obj:{'name':'tom','age':18}
26             },
27             methods:{
28             },
29             computed:{
30             },
31             watch:{
32                 name:{
33                     handler:function (newVal,oldVal) {
34                         console.log(newVal,oldVal);
35                     }
36                 },
37                 arr:{
38                     // 只能監聽到 數組長度的變化,若是裏面元素髮生變化,是監聽不到的
39                     // 此時若是想要 修改裏面元素 還想被監聽到,就不能使用簡單的 = 號了,
40                     // 使用 app.$set(this.arr,0,'4'); 這是就能夠被監聽到了
41                     handler:function (newVal,oldVal) {
42                         console.log(newVal,oldVal);
43 
44                     },
45                     // deep:true  沒用,深度監聽 也不能夠
46                 },
47                 obj:{
48                     // 只能監聽到 整個對象的變化
49                     handler:function (newVal,oldVal) {
50                         console.log(newVal,oldVal);
51                     },
52                     deep:true // 可是,deep 只能監聽 對象已有屬性變化,若是新增仍是監聽不到,用  app.$set()
53                 }
54             }
55         })
56     </script>
57 </body>
58 </html>
View Code

 

vue 的 組件:

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <my_star></my_star>
12     </div>
13     <hr>
14     <div class="box2" >
15         <my_star></my_star>
16     </div>
17 
18     <script src="vue.js"></script>
19     <script>
20         Vue.component('my_star',{
21            template:`<div style="1px solid red;">我是div標籤 by--{{title}}</div>`,
22             data:function () {
23                 return {
24                     title:'tom'
25                 }
26             },
27             methods:function () {
28             }
29         });
30         const app1 = new Vue({
31             el:'.box', // 1,指定 vue 的做用域
32             data:{     // 2,放入數據
33             },
34             methods:{
35             },
36             computed:{
37             },
38             watch:{
39             }
40         });
41         const app2 = new Vue({
42             el:'.box2', // 1,指定 vue 的做用域
43             data:{     // 2,放入數據
44             },
45             methods:{
46             },
47             computed:{
48             },
49             watch:{
50             }
51         })
52     </script>
53 </body>
54 </html>
全局註冊 組件
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <my_star></my_star>
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         let my_star = {
16             template:`<div style="1px solid red;">我是div標籤 by--{{title}}</div>`,
17             data:function () {
18                 return {
19                     title:'tom'
20                 }
21             },
22             methods:function () {
23             }
24         };
25         const app1 = new Vue({
26             el:'.box', // 1,指定 vue 的做用域
27             data:{     // 2,放入數據
28             },
29             methods:{
30             },
31             computed:{
32             },
33             watch:{
34             },
35             components:{
36                 my_star:my_star
37             }
38         });
39 
40     </script>
41 </body>
42 </html>
局部註冊 組件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>hello world</title>
</head>
<body>
    <div class="box" >
        <my_star></my_star>
    </div>
    <script src="vue.js"></script>
    <script>
        let star = {
            template:`<div style="1px solid blue;">我是子組件 --{{title}}</div>`,
            data:function () {
                return {
                    title:'jane'
                }
            },
            methods:function () {
            },
        };
        let my_star = {
            template:`<div style="1px solid red;">組件--{{title}}<star></star>     </div> `,
            data:function () {
                return {
                    title:'tom'
                }
            },
            methods:function () {
            },
            components: {
                star:star
            }
        };
        const app1 = new Vue({
            el:'.box', // 1,指定 vue 的做用域
            data:{     // 2,放入數據
            },
            methods:{
            },
            computed:{
            },
            watch:{
            },
            components:{
                my_star:my_star
            }
        });

    </script>
</body>
</html>
子組件 內再註冊 組件

 

父子組件 通訊 :

父 ---->   子  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <father></father>
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         let son = {
16             template:`<div>我是子組件 :[{{fa_say}}]</div>`,
17             props:['fa_say']
18         };
19         let father = {
20             template:`
21                 <div>我是父組件  <son v-bind:fa_say="fa_say"></son> </div>
22             `,
23             components: {
24                 son:son
25             },
26             data:function () {
27                 return {
28                     fa_say:'你好 son'
29                 }
30             }
31 
32         };
33         const app1 = new Vue({
34             el:'.box', // 1,指定 vue 的做用域
35             data:{     // 2,放入數據
36             },
37             methods:{
38             },
39             computed:{
40             },
41             watch:{
42             },
43             components:{
44                 father:father
45             }
46         });
47 
48     </script>
49 </body>
50 </html>
View Code

 

子父組件 通訊 :

子 --->  父  

須要 兒子  先發射 emit  一個事件,  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <father></father>
12     </div>
13     <script src="vue.js"></script>
14     <script>
15         let son = {
16             template:`<div>我是子組件
17                 <button @click="myEvt">點我</button>
18             </div>`,
19             methods: {
20                 myEvt:function () {
21                     this.$emit('sonEmit','我是你的兒子');
22                 }
23             }
24         };
25         let father = {
26             template:`
27                 <div>我是父組件  <son @sonEmit="myEvt"></son> </div>
28             `,
29             components: {
30                 son:son
31             },
32             methods:{
33                 myEvt:function (data) {
34                     console.log(data);
35                 }
36             }
37 
38         };
39         const app1 = new Vue({
40             el:'.box', // 1,指定 vue 的做用域
41             data:{     // 2,放入數據
42             },
43             methods:{
44             },
45             computed:{
46             },
47             watch:{
48             },
49             components:{
50                 father:father
51             }
52         });
53 
54     </script>
55 </body>
56 </html>
子父組件 通訊

 

非父子組件 通訊 :

這時須要一個第三方 來做爲調度,  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <c1></c1>
12         <c2></c2>
13 
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         let middle = new Vue();
18 
19         let c1 = {
20             template:` <div>
21             組件1
22             <button @click="myEvt">發送消息</button>
23             </div> `,
24             methods:{
25                 myEvt:function () {
26                     middle.$emit('myEmit','我是組件1,你呢?')
27                 }
28             }
29         };
30         let c2 = {
31             template:` <div>組件2</div> `,
32             mounted:function (res) {
33                 // mounted 是當 組件加載以後  就執行的函數
34                 middle.$on('myEmit',res=>{
35                     // console.log(this); // 要注意this 的問題,  
36                     console.log('組件二中:  ',res);
37                 })
38             }
39 
40         };
41 
42         const app1 = new Vue({
43             el:'.box', // 1,指定 vue 的做用域
44             data:{     // 2,放入數據
45             },
46             methods:{
47             },
48             computed:{
49             },
50             watch:{
51             },
52             components:{
53                 c1:c1,
54                 c2:c2
55             }
56         });
57 
58     </script>
59 </body>
60 </html>
View Code

 

混合   :

共用一個代碼塊,  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <c1></c1>
12         <hr>
13         <c2></c2>
14 
15     </div>
16     <script src="vue.js"></script>
17     <script>
18         let base = {
19             data() {
20                 return {
21                     title:'hello world'
22                 }
23             },
24             methods:{
25                 // 也能夠註冊事件
26             }
27         };
28         let c1 = {
29             template:` <div>{{title}}</div> `,
30             methods:{
31             },
32             mixins:[base]
33         };
34         let c2 = {
35             template:` <div>{{title}}</div> `,
36             methods:{
37             },
38             mixins:[base]
39         };
40 
41         const app1 = new Vue({
42             el:'.box', // 1,指定 vue 的做用域
43             data:{     // 2,放入數據
44             },
45             methods:{
46             },
47             computed:{
48             },
49             watch:{
50             },
51             components:{
52                 c1:c1,
53                 c2:c2
54             }
55         });
56 
57     </script>
58 </body>
59 </html>
View Code

 

組件中 開槽 slot:  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <c1>
12             <a href="http://www.baidu.com">百度一下</a>
13         </c1>
14     </div>
15     <script src="vue.js"></script>
16     <script>
17         let c1 = {
18             template:` <div>  <slot></slot>  </div> `,
19             methods:{
20             },
21         };
22         const app1 = new Vue({
23             el:'.box', // 1,指定 vue 的做用域
24             data:{     // 2,放入數據
25             },
26             methods:{
27             },
28             computed:{
29             },
30             watch:{
31             },
32             components:{
33                 c1:c1,
34             }
35         });
36 
37     </script>
38 </body>
39 </html>
View Code

 

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <c1>
12             <a slot="s1" href="http://www.baidu.com">百度一下</a>
13             <a slot="s2" href="http://www.google.com">谷歌一下</a>
14         </c1>
15     </div>
16     <script src="vue.js"></script>
17     <script>
18         let c1 = {
19             template:` <div>
20                              <slot name="s1"></slot>
21                              <slot name="s2"></slot>
22                         </div> `,
23             methods:{
24             },
25         };
26         const app1 = new Vue({
27             el:'.box', // 1,指定 vue 的做用域
28             data:{     // 2,放入數據
29             },
30             methods:{
31             },
32             computed:{
33             },
34             watch:{
35             },
36             components:{
37                 c1:c1,
38             }
39         });
40 
41     </script>
42 </body>
43 </html>
View Code

 

vue 路由: 

vue經過 路由  和 組件 能夠構建一個 單頁面的應用,  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link to="/">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link to="/course">課程</router-link>
13 
14         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
15     </div>
16     <script src="vue.js"></script>
17     <script src="vue-router.js"></script>
18     <script>
19         //1, 定義路由 和 組件的匹配規則
20         let url = [
21             {
22                 path:'/',
23                 component:{
24                     template: `<div>這是組件1,根目錄</div> `
25                 }
26             },
27             {
28                 path:'/course',
29                 component:{
30                     template: `<div>這是組件2,課程目錄</div> `
31                 }
32             }
33         ];
34         // 2 實例化  VueRouter 對象
35         let router = new VueRouter({
36             routes:url
37         });
38         // 3把 實例化的 router 放到 app1中
39         const app1 = new Vue({
40             el:'.box',
41             router:router,
42 
43         });
44 
45     </script>
46 </body>
47 </html>
簡單路由 demo

 

給url 起別名:  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'course'}">課程</router-link>
13 
14         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
15     </div>
16     <script src="vue.js"></script>
17     <script src="vue-router.js"></script>
18     <script>
19         //1, 定義路由 和 組件的匹配規則
20         let url = [
21             {
22                 path:'/',
23                 name:'home',// 起別名
24                 component:{
25                     template: `<div>這是組件1,根目錄</div> `
26                 }
27             },
28             {
29                 path:'/course',
30                 name:'course', // 起別名
31                 component:{
32                     template: `<div>這是組件2,課程目錄</div> `
33                 }
34             }
35         ];
36         // 2 實例化  VueRouter 對象
37         let router = new VueRouter({
38             routes:url
39         });
40         // 3把 實例化的 router 放到 app1中
41         const app1 = new Vue({
42             el:'.box',
43             router:router,
44 
45         });
46 
47     </script>
48 </body>
49 </html>
View Code

 

路由的參數  : 

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'course'}">課程</router-link>
13         <router-link :to="{name:'user',params:{username:'xxx'},query:{age:18}}">用戶</router-link>
14 
15         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
16     </div>
17     <script src="vue.js"></script>
18     <script src="vue-router.js"></script>
19     <script>
20         //1, 定義路由 和 組件的匹配規則
21         let url = [
22             {
23                 path:'/',
24                 name:'home',// 起別名
25                 component:{
26                     template: `<div>這是組件1,根目錄</div> `
27                 }
28             },
29             {
30                 path:'/course',
31                 name:'course', // 起別名
32                 component:{
33                     template: `<div>這是組件2,課程目錄</div> `
34                 }
35             },
36             {
37                 path:'/user/:name',
38                 name:'user', // 起別名
39                 component:{
40                     template: `<div>我是【{{this.$route.params.username}}】,我今年【{{this.$route.query.age}}】 歲</div> `
41                 },
42                 mounted:function () {
43                     console.log(this.$route);
44                 }
45             }
46         ];
47         // 2 實例化  VueRouter 對象
48         let router = new VueRouter({
49             routes:url
50         });
51         // 3把 實例化的 router 放到 app1中
52         const app1 = new Vue({
53             el:'.box',
54             router:router,
55 
56         });
57 
58     </script>
59 </body>
60 </html>
View Code

 

手動路由:

須要用 this.$router ,

注: router  是 VueRouter 的實例化對象, 而 route 只是當前url 的信息,  

 

this.$router.push() 就能夠改變路由,  

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12 
13         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
14     </div>
15     <script src="vue.js"></script>
16     <script src="vue-router.js"></script>
17     <script>
18         //1, 定義路由 和 組件的匹配規則
19         let url = [
20             {
21                 path:'/',
22                 name:'home',// 起別名
23                 component:{
24                     template: `<div>這是組件1,根目錄
25                                 <button @click="clickEvt">點擊登陸</button>
26                               </div> `,
27                     methods:{
28                     clickEvt:function () {
29                         console.log(this.$route);
30                         console.log(this.$router);
31                         // console.log(this.$el);
32                         // console.log(this.$data);
33 
34                         this.$router.push('/login');  // $router.push 方法 手動路由,
35                         }
36                     }
37                 },
38 
39             },
40             {
41                 path:'/login',
42                 name:'login', // 起別名
43                 component:{
44                     template: `<div>這是登陸頁面</div> `
45                 }
46             },
47 
48         ];
49         // 2 實例化  VueRouter 對象
50         let router = new VueRouter({
51             routes:url
52         });
53         // 3把 實例化的 router 放到 app1中
54         const app1 = new Vue({
55             el:'.box',
56             router:router,
57 
58         });
59 
60     </script>
61 </body>
62 </html>
手動路由

 

路由下配置子路由:   

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'user'}">查看用戶</router-link> <!--router-link 底層是 a 標籤  -->
13 
14         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
15     </div>
16     <script src="vue.js"></script>
17     <script src="vue-router.js"></script>
18     <script>
19         //1, 定義路由 和 組件的匹配規則
20         let url = [
21             {
22                 path:'/',
23                 name:'home',// 起別名
24                 component:{
25                     template: `<div>這是組件1,根目錄
26                                 <button @click="clickEvt">點擊登陸</button>
27                               </div> `,
28                     methods:{
29                     clickEvt:function () {
30                         this.$router.push('/login');
31                         }
32                     }
33                 },
34             },
35             {
36                 path:'/user',
37                 name:'user', // 起別名
38                 component:{
39                     template: `<div>這是用戶頁面
40                             <hr>
41                             <router-link :to="{name:'userDetail1'}">用戶詳情1</router-link>
42                             <router-link :to="{name:'userDetail2'}">用戶詳情2</router-link>
43                             <router-view></router-view>
44                         </div> `
45                 },
46                 children:[
47                     {
48                         path:'userDetail1',
49                         name:'userDetail1',
50                         component:{
51                             template: `<div>詳情頁面1</div> `
52                         },
53                     },
54                     {
55                         path:'userDetail2',
56                         name:'userDetail2',
57                         component:{
58                             template: `<div>詳情頁面2</div> `
59                         },
60                     }
61 
62 
63 
64                 ]
65             },
66 
67         ];
68         // 2 實例化  VueRouter 對象
69         let router = new VueRouter({
70             routes:url
71         });
72         // 3把 實例化的 router 放到 app1中
73         const app1 = new Vue({
74             el:'.box',
75             router:router,
76 
77         });
78 
79     </script>
80 </body>
81 </html>
配置子路由
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'user'}">查看用戶</router-link> <!--router-link 底層是 a 標籤  -->
13 
14         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
15     </div>
16     <script src="vue.js"></script>
17     <script src="vue-router.js"></script>
18     <script>
19         //1, 定義路由 和 組件的匹配規則
20         let url = [
21             {
22                 path:'/',
23                 name:'home',// 起別名
24                 component:{
25                     template: `<div>這是組件1,根目錄
26                                 <button @click="clickEvt">點擊登陸</button>
27                               </div> `,
28                     methods:{
29                     clickEvt:function () {
30                         this.$router.push('/login');
31                         }
32                     }
33                 },
34             },
35             {
36                 path:'/user',
37                 name:'user', // 起別名
38                 redirect:{
39                     name:'userDetail1'
40                 },
41                 component:{
42                     template: `<div>這是用戶頁面
43                             <hr>
44                             <router-link :to="{name:'userDetail1'}">用戶詳情1</router-link>
45                             <router-link :to="{name:'userDetail2'}">用戶詳情2</router-link>
46                             <router-view></router-view>
47                         </div> `
48                 },
49                 children:[
50                     {
51                         path:'userDetail1',
52                         name:'userDetail1',
53                         component:{
54                             template: `<div>詳情頁面1</div> `
55                         },
56                     },
57                     {
58                         path:'userDetail2',
59                         name:'userDetail2',
60                         component:{
61                             template: `<div>詳情頁面2</div> `
62                         },
63                     }
64 
65 
66 
67                 ]
68             },
69 
70         ];
71         // 2 實例化  VueRouter 對象
72         let router = new VueRouter({
73             routes:url
74         });
75         // 3把 實例化的 router 放到 app1中
76         const app1 = new Vue({
77             el:'.box',
78             router:router,
79 
80         });
81 
82     </script>
83 </body>
84 </html>
redirect 直接到 一個子路由

 

路由鉤子函數:

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'user'}">查看用戶</router-link> <!--router-link 底層是 a 標籤  -->
13 
14         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
15     </div>
16     <script src="vue.js"></script>
17     <script src="vue-router.js"></script>
18     <script>
19         //1, 定義路由 和 組件的匹配規則
20         let url = [
21             {
22                 path:'/',
23                 name:'home',// 起別名
24                 component:{
25                     template: `<div>這是組件1,根目錄
26                                 <button @click="clickEvt">點擊登陸</button>
27                               </div> `,
28                     methods:{
29                     clickEvt:function () {
30                         this.$router.push('/login');
31                         }
32                     }
33                 },
34 
35             },
36             {
37                 path:'/login',
38                 name:'login', // 起別名
39                 component:{
40                     template: `<div>這是登陸頁面</div> `
41                 }
42             },
43             {
44                 path:'/user',
45                 name:'user', // 起別名
46                 component:{
47                     template: `<div>這是用戶頁面</div> `
48                 }
49             },
50 
51         ];
52         // 2 實例化  VueRouter 對象
53         let router = new VueRouter({
54             routes:url
55         });
56         // 路由鉤子函數
57         router.beforeEach(function (to,from,next) {
58             console.log(to);   // 去哪一個 route
59             console.log(from); // 從哪一個 route 來
60             console.log(next); // 下一步 幹什麼
61             if (to.path === '/user' ){
62                 next('/login'); // 若是用戶沒登陸 就查看 user ,要跳到 login
63             }else{
64                 next(); // 正常狀況 直接next();  若是沒有 next() 或者 next(false);這樣就不跳轉了,
65             }
66 
67 
68         });
69 
70         // 3把 實例化的 router 放到 app1中
71         const app1 = new Vue({
72             el:'.box',
73             router:router,
74 
75         });
76 
77     </script>
78 </body>
79 </html>
基本用法 
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'user'}">查看用戶</router-link> <!--router-link 底層是 a 標籤  -->
13 
14         <router-view></router-view>  <!-- 用於放 url 中path對應的組件 -->
15     </div>
16     <script src="vue.js"></script>
17     <script src="vue-router.js"></script>
18     <script>
19         //1, 定義路由 和 組件的匹配規則
20         let url = [
21             {
22                 path:'/',
23                 name:'home',// 起別名
24                 component:{
25                     template: `<div>這是組件1,根目錄
26                                 <button @click="clickEvt">點擊登陸</button>
27                               </div> `,
28                     methods:{
29                     clickEvt:function () {
30                         this.$router.push('/login');
31                         }
32                     }
33                 },
34             },
35             {
36                 path:'/login',
37                 name:'login', // 起別名
38                 component:{
39                     template: `<div>這是登陸頁面</div> `
40                 }
41             },
42             {
43                 path:'/user',
44                 name:'user', // 起別名
45                 meta:{   // 元信息配置
46                     must_login:true,
47                 },
48                 component:{
49                     template: `<div>這是用戶頁面</div> `
50                 }
51             },
52 
53         ];
54         // 2 實例化  VueRouter 對象
55         let router = new VueRouter({
56             routes:url
57         });
58         // 路由鉤子函數
59         router.beforeEach(function (to,from,next) {
60             console.log(to);   // 去哪一個 route
61             console.log(from); // 從哪一個 route 來
62             console.log(next); // 下一步 幹什麼
63             if (to.meta.must_login){
64                 next('/login'); // 若是用戶沒登陸 就查看 user ,要跳到 login
65             }else{
66                 next(); // 正常狀況 直接next();  若是沒有 next() 或者 next(false);這樣就不跳轉了,
67             }
68 
69 
70         });
71 
72         // 3把 實例化的 router 放到 app1中
73         const app1 = new Vue({
74             el:'.box',
75             router:router,
76 
77         });
78 
79     </script>
80 </body>
81 </html>
配置 route 裏的元信息 meta

還有 router.afterEach():  不過它沒有 next 操做,  

 

 

命名的 router-view   

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11         <router-link :to="{name:'home'}">首頁</router-link> <!--router-link 底層是 a 標籤  -->
12         <router-link :to="{name:'user'}">查看用戶</router-link> <!--router-link 底層是 a 標籤  -->
13         <router-view name="head"></router-view>  <!--專門展現 頭部 head -->
14         <router-view></router-view>
15         <router-view name="foot"></router-view> <!--專門展現 尾部 foot  -->
16     </div>
17     <script src="vue.js"></script>
18     <script src="vue-router.js"></script>
19     <script>
20         let url = [
21             {
22                 path:'/',
23                 name:'home',// 起別名
24                 component:{
25                     template: `<div>這是組件1,根目錄
26                                 <button @click="clickEvt">點擊登陸</button>
27                               </div> `,
28                     methods:{
29                     clickEvt:function () {
30                         this.$router.push('/login');
31                         }
32                     }
33                 },
34             },
35             {
36                 path:'/user',
37                 name:'user', // 起別名
38                 components: {
39                     head:{
40                         template: `<div>頭部頁面 </div> `
41                     },
42                     foot:{
43                         template: `<div>尾部頁面 </div> `
44                     }
45 
46                 },
47 
48             },
49 
50         ];
51         let router = new VueRouter({
52             routes:url,
53             mode:'history' // 能夠整潔 地址欄中的 url
54         });
55         const app1 = new Vue({
56             el:'.box',
57             router:router,
58 
59         });
60 
61     </script>
62 </body>
63 </html>
View Code

其餘:  

mode = 'history' 小參數

 

vue 生命週期: 

https://www.cnblogs.com/GGGG-XXXX/articles/9467297.html

 

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 </head>
 9 <body>
10     <div class="box" >
11        {{username}}
12     </div>
13     <script src="vue.js"></script>
14     <script src="vue-router.js"></script>
15     <script>
16         const app1 = new Vue({
17             el:'.box',
18             data:{
19                 username:'tom'
20             },
21             methods:{
22                 func:function () {
23                     console.log('hello');     
24                 }
25             },
26             beforeCreate(){ // 1, 鉤子函數 1  
27                 console.group('beforeCreate');
28                 console.log(this.$el);   //undefined
29                 console.log(this.username); //undefined
30                 console.log(this.func); //undefined
31             },
32             created(){ // 2, 鉤子函數 2
33                 console.group('created');
34                 console.log(this.$el); //undefined
35                 console.log(this.username); // tom
36                 console.log(this.func); // ƒ () { ... }
37 
38             },
39             beforeMount(){ // 3, 鉤子函數 3
40                 console.group('beforeMount 頁面真實加載完成以前 , 下面就要編譯 dom, 就是作編譯 一些例如 router-link router-view 等的工做');
41                 console.log(this.$el); //  <div>...</div>
42                 console.log(this.username); // tom
43                 console.log(this.func); // ƒ () { ... }
44             },
45             mounted(){ // 4, 鉤子函數 4  *******經常使用******
46                 console.group('mounted 頁面真實加載完成以後');
47                 console.log(this.$el); //  <div>...</div>
48                 console.log(this.username); // tom
49                 console.log(this.func); // ƒ () { ... }
50             },
51             beforeUpdate(){ // 5, 鉤子函數 5   *******經常使用******
52                 console.group('beforeUpdate  更改數據 以前 ');
53                 console.log(this.$el); //  <div>...</div>
54                 console.log(this.username); // tom
55                 console.log(this.func); // ƒ () { ... }
56             },
57             updated(){ // 6, 鉤子函數 6    *******經常使用******
58                 console.group('updated  更改數據 以後');
59                 console.log(this.$el); //  <div>...</div>
60                 console.log(this.username); // tom
61                 console.log(this.func); // ƒ () { ... }
62             },
63 
64 
65             beforeDestroy(){ // 7, 鉤子函數 7  app.$destroy(); 會觸發它們,
66                 console.group('beforeDestroy');
67                 console.log(this.$el); 
68                 console.log(this.username); 
69                 console.log(this.func); 
70             },
71             destroyed(){ // 8, 鉤子函數 8
72                 console.group('destroyed 一旦銷燬以後 vue 的實例對象就不能再用了');
73                 console.log(this.$el); 
74                 console.log(this.username); 
75                 console.log(this.func); 
76             },
77 
78         });
79 
80     </script>
81 </body>
82 </html>
生命週期

 

 

 

element  :

https://element.eleme.cn/#/zh-CN

如今不少網站都是 vue +  element 來搭,不會用 jquery 和 bootstrap ,

可是,先後端不分離仍是會用 jquery 和 bootstrap 來搭 

 

導航條:

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 
 9 
10     <script src="vue.js"></script>
11     <script src="vue-router.js"></script>
12     <!-- element -->
13     <link rel="stylesheet" href="element/index.css">
14     <script src="element/index.js"></script>
15     <!-- 引入樣式 -->
16 <!--    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">-->
17     <!-- 引入組件庫 -->
18 <!--    <script src="https://unpkg.com/element-ui/lib/index.js"></script>-->
19     <style>
20         .el-menu{
21             display: flex;
22             justify-content: center;
23         }
24     </style>
25 </head>
26 <body>
27     <template id="header">
28         <div class="page_head">
29 <!--            <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">-->
30             <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" >
31                   <el-menu-item index="0">首頁</el-menu-item>
32                   <el-menu-item index="1">免費課程</el-menu-item>
33                   <el-menu-item index="2">輕課</el-menu-item>
34                   <el-menu-item index="3">學位課程</el-menu-item>
35                   <el-menu-item index="4">智能題庫</el-menu-item>
36             </el-menu>
37 
38         </div>
39     </template>
40     <div class="box">
41         <my_header></my_header>
42     </div>
43     <script>
44         let my_header = {
45             template:'#header',// 這裏是使用 選擇器
46             data(){
47                 return {
48                     activeIndex:'0',
49                 }
50             }
51         };
52         const app = new Vue({
53             el:'.box',
54             components: {
55                 my_header:my_header,
56             }
57         });
58     </script>
59 </body>
60 </html>
View Code
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="utf-8">
 5     <meta http-equiv="X-UA-Compatible" content="IE=edge">
 6     <meta name="viewport" content="width=device-width, initial-scale=1">
 7     <title>hello world</title>
 8 
 9 
10     <script src="vue.js"></script>
11     <script src="vue-router.js"></script>
12     <!-- element -->
13     <link rel="stylesheet" href="element/index.css">
14     <script src="element/index.js"></script>
15     <!-- 引入樣式 -->
16 <!--    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">-->
17     <!-- 引入組件庫 -->
18 <!--    <script src="https://unpkg.com/element-ui/lib/index.js"></script>-->
19     <style>
20         .el-menu{
21             display: flex;
22             justify-content: center;
23         }
24     </style>
25 </head>
26 <body>
27     <template id="header">
28         <div class="page_head">
29 <!--            <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">-->
30             <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" :router="true">
31                   <el-menu-item index="/">首頁</el-menu-item>
32                   <el-menu-item index="/course">免費課程</el-menu-item>
33                   <el-menu-item index="2">輕課</el-menu-item>
34                   <el-menu-item index="3">學位課程</el-menu-item>
35                   <el-menu-item index="4">智能題庫</el-menu-item>
36             </el-menu>
37 
38         </div>
39     </template>
40     <div class="box">
41         <my_header></my_header>
42         <router-view></router-view>
43     </div>
44     <script>
45         let my_header = {
46             template:'#header',// 這裏是使用 選擇器
47             data(){
48                 return {
49                     activeIndex:'/',
50                 }
51             }
52         };
53         let url = [
54             {
55                 path:'/',
56                 component:{
57                     template:`<div>這是首頁</div>`
58                 },
59             },
60             {
61                 path:'/course',
62                 component:{
63                     template:`<div>這是免費課程頁面</div>`
64                 },
65             },
66         ];
67         let router = new VueRouter({
68             routes:url,
69             mode:'history',
70         });
71         const app = new Vue({
72             el:'.box',
73             router:router,
74             components: {
75                 my_header:my_header,
76             }
77         });
78     </script>
79 
80 
81 
82 </body>
83 </html>
element el-menu 組件中 router 屬性開啓

 

npm 管理項目   :

https://www.cnblogs.com/GGGG-XXXX/articles/9503423.html

 

npm run 能夠運行 package.json 中的腳本,  

 

webpack 打包工具   :

默認入口文件 index.js ,出口文件  main.js  ,   webpack 中的文件支持 es6 的 export  和 import   

 

 

vue-cli   :

https://files.cnblogs.com/files/zach0812/vue-cli%E6%90%AD%E5%BB%BA%E9%A1%B9%E7%9B%AE.zip

下到全局: npm install vue-cli -g  

而後切換到工做目錄: vue init webpack 項目名字   

 

vuex : 

https://www.cnblogs.com/GGGG-XXXX/articles/9467325.html

npm install vuex --save 

爲了解決組件間通訊麻煩的問題,出現了 vue-x  ,它是用來管理共用數據的

 

 

mpvue 中使用: 

https://files.cnblogs.com/files/zach0812/vuex%E7%9A%84%E7%94%A8%E6%B3%95state.zip

 

 

axios : 

npm install axios --save  

它是向後端發送ajax 的工具,固然,你也可使用原生 js ,或者使用jquery ,

axios 不能註冊到 vue 的根實例中,可是,咱們還想經過this.$ 來使用axios 

能夠經過加到原型中來幹: 

若是安裝失敗能夠:

npm cache clean --force

 

 

vue-cookie :

將數據保存到 本地瀏覽器,

相關文章
相關標籤/搜索