web應用程序html
server端創建socket,不斷地accept,當收到客戶端鏈接信號以後,服務端向客戶端發送數據,將html網頁打開,read出來,併發送至客戶端,這樣客戶端就能夠瀏覽到網頁的內容python
http協議:mysql
包頭裏面的數據用 一個「\r\n」來區分,最後使用兩個「\r\n」來區分數據git
GET協議把數據放在了包頭裏面,POST協議把數據放在包頭的最後面web
GET提交的數據以「?」區分,參數之間以「&」進行鏈接ajax
相應格式:正則表達式
協議版本 狀態碼 狀態碼的緣由短語 相應首部字段 主體sql
web框架 yuan功能總結
main.py: 啓動文件,封裝了socket
1 urls.py: 路徑與視圖函數映射關係 ---- url控制器
2 views.py 視圖函數,固定有一個形式參數:environ -----視圖函數,
3 templates文件夾: html文件 -----模板
4 models: 在項目啓動前,在數據庫中建立表結構 ----- 與數據庫相關
Django的安裝與啓動
建立應用:python manage.py startapp blog
urlpatterns = [ re_path(r'^articles/2003/$', views.special_case_2003), re_path(r'^articles/([0-9]{4})/$', views.year_archive), re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
有名分組:在組前面加上?P<組名> 便可,在傳參時的形參必須是「組名」,不然會出錯
命名空間:namespace
app01.urls:
須要加上
app_name = "app01"
urlpatterns=[
re_path(r'^index/',views.index,name="index"),
]
同理在ap02.urls加上相同的配置
views.py:
def index(request):
return HttpResponse(reverse("app01:index"))
須要加上反向解析
註冊自定義轉換器
先建一個類
class FourDigitYearConverter:
regex = '[0-9]{2}' #正則表達式的公式
def to_python(self,value):
return int(value)
def to_url(self,value):
return '%04d' % value
在項目中註冊轉換器
# 註冊定義的url轉換器
register_converter(FourDigitYearConverter,'mm') #FourDigitYearConverter : 爲以上類名
以後在urls裏能夠直接path使用
path('articles/<mm:month>/',views.month_archive)
模板語法 只有兩個
1.{{}}
能夠在
return render(request,'index.html',locals()) 這樣就把該函數裏的所有全局變量都傳過去了
同時在index.html能夠經過 . 來過去數據 如一個數組l=【‘123’,‘456’,‘789’】 ,在html能夠經過l.2 獲取到數據456
2{%%}
{%if%}
{%endif%}
自定義標籤與過濾器
1.在settings的INSTALLED_APPS加上當前app的名稱,否則django沒法找到自定義的simple_tag.
2.在app文件夾裏面添加templatetags模塊(模塊名只能是templatetags)
3.在templatetags裏面建立任意py文件
4.在該py文件裏面引入
from django import template
register = template.Library() # 固定名字
@register.filter #加上裝飾器,這個爲模板過濾器
def filter_multi(x,y):
return x*y
@register.simple_tag #標籤過濾器
def filter_tag(x,y):
return x*y
5.在html文件裏面讀取該過濾器
{%load py的文件名%}
6.使用
{{ 2 | filter_multi:5 }}
{% filter_tag 5 6 %}
繼承:extends
在一個base.html 裏面把模板寫好
在另外一個html裏面引入base.html
{% extends "base.html" %}
這時候能夠在下面繼續添加block裏面的內容
{{% block title %}
<title>第一個</title>
{% endblock title%}
模型層ORM
ORM 對象-關係-映射
經過編寫ORM層,控制pysql轉換成db語句,再去控制db數據庫。py文件裏面經過建立一個類
生成表模型
1.建立模型
from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) title=models.CharField(max_length=32) state=models.BooleanField() pub_date=models.DateField() price=models.DecimalField(max_digits=8,decimal_places=2) publish=models.CharField(max_length=32)
建立一個app,而後在app項目文件下的models下建立類數據庫
2.配置連接數據庫settingsdjango
在項目文件下的settings文件設置下,設置數據庫信息
DATABASES = { 'default':{ 'ENGINE':'django.db.backends.mysql', 'NAME':'bms', #建立數據庫名字 'USER':'root', #連接數據庫用戶名 'PASSWORD':'', #連接數據庫密碼 "HOST":'127.0.0.1', #目標數據庫地址 'PORT':3306 #目標數據庫端口 } }
3.確認信息
①在項目app文件下的__init__插入代碼:
import pymysql pymysql.install_as_MySQLdb()
②確保配置文件中的INSTALLED_APPS中寫入咱們建立的app名稱
如在installed_apps 下添加app文件名
最後,能夠進行數據遷移
python manage.py makemigrations python manage.py migrate
數據庫的創建create:
方式一:
book_obj = Book.objects.create(title='第一個數據庫',state=True,price=500,pub_date="2012-12-12",publish='人民出版社') #裏面的數據格式須要與創建時的數據格式一致
方式二:
book_obj = Book(title='方式二',publish='機械出版社',state=True,pub_date="2010-12-11",price=10.12)
book_obj.save() #須要多一個save
查詢表:
Django 本身生成的一個數據對象:QuerySet: [obj1,obj2,obj3....]
能夠經過語句Book.object ---> 生成QuerySet數據
Book.object.all() 能夠讀取全部的數據
values方法: 返回和調用都是QuerySet
book_obj = Book.objects.values('price')
至關於
list = []
for obj in QuerySet:
list.append{'price':obj['price']}
.... #若是在values後面加值,就繼續append
values_list方法: 返回和調用都是QuerySet
book_obj = Book.objects.values_list('price')
distinct:去重 從返回結果中剔除重複紀錄
表的查詢
一對多的查詢:
A---B
若是關聯表在A表中:
A----->B :正向查詢
反過來經過B去查A 則是反向查詢,主要看關聯表在哪張表裏面
正向查詢:看字段
反向查詢:看錶名:表名小寫__set.all()
聚合與分組查詢
關鍵字:annotate
總結 跨表的分組查詢的模型:
# 每個後表模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段))
AJAX
特色:
1.使用JavaScript向服務器發送異步請求
2.局部刷新
$(".Ajax").click(function () {
$.ajax({
url:"/test_ajax/", //請求地址
type:"get", //請求的類型poet或者是get
success:function (data) {
$(".haha").html(data)
console.log(data)
}
})
})
數據之間的傳輸 經過使用json序列化
在py裏面使用json.dump序列化
在Ajax裏面使用JSON.parse 反序列化進行解析
利用Form表單進行文件上傳
def file_put(request): if request.method=="POST": print('123') print(request.POST) print(request.FILES) file_obj = request.FILES.get("tou") with open(file_obj.name,'wb') as f: for i in file_obj: f.write(i) return HttpResponse('OK') return render(request, "file_put.html")
批量導入數據庫的數據:
''' 批量導入數據: Booklist=[] for i in range(100): book = Book(user="book_%s"%i,pwd=i*i) Booklist.append(book) Book.objects.bulk_create(Booklist) '''
分頁器:
book_list = Book.objects.all() paginator = Paginator(book_list,10) print("count:", paginator.count) # 數據總數 print("num_pages", paginator.num_pages) # 總頁數 print("page_range", paginator.page_range) # 頁碼的列表 page1=paginator.page(4) #第4頁的page對象數據 for i in page1: #遍歷 print(i) print(page1.object_list) #直接拿出該page的全部對象
#捕捉EmptyPage錯誤信息時作的處理
try:
current_page = int(request.GET.get("page",1))
page1 = paginator.page(current_page)
except EmptyPage as e:
page1 = paginator.page(1)
print(page2.has_next()) #是否有下一頁 print(page2.next_page_number()) #下一頁的頁碼 print(page2.has_previous()) #是否有上一頁 print(page2.previous_page_number()) #上一頁的頁碼
form組件
form.is_valid() #:返回布爾值 form.cleaned_data #:{"name":"yuan","email":"123@qq.com"} 返回匹配成功的字典 form.errors #返回對應類字段的錯誤信息 :{"name":[".........."]}
from django.forms import widgets
class UserForm(forms.Form): #用於認證用 name = forms.CharField(max_length=32,label="用戶名", widget=widgets.TextInput(attrs={"class":"form-control"}),error_messages={「required」:「該字段不能爲空」}) #attr即爲修改樣式,error_message修改默認的錯誤信息,必須爲required這個鍵名 pwd = forms.CharField(min_length=4) r_pwd = forms.CharField(min_length=4) email = forms.CharField() tel = forms.CharField(min_length=4,max_length=32) def form_test(request): if request.method == 'POST': form = UserForm(request.POST) if form.is_valid(): #校驗是否驗證經過,同時會把錯誤、正確的信息放在兩個字典裏面 print(form.cleaned_data) else: print(form.cleaned_data) print(form.errors) # ErrorDict : {"校驗錯誤的字段":["錯誤信息",]} print(form.errors.get("name")) # ErrorList ["錯誤信息",] return HttpResponse("OK") form = UserForm() return render(request, "form_test.html", locals()) form = UserForm() return render(request,"form_test.html")
在html裏面想打印錯誤信息,能夠{{form.name.errors}} 這樣能夠獲取name裏的錯誤信息
利用form表單組件 進行文件上傳,使用FormData
$(".login_btn").click(function () { var form_data = new FormData(); //首先實例化一個FormData form_data.append("user",$("#id_user").val()) //再往裏面添加數據 form_data.append("pwd",$("#id_pwd").val()) form_data.append("r_pwd",$("#id_r_pwd").val()) form_data.append("email",$("#id_email").val()) form_data.append("img",($("#avater")[0].files[0])) //該爲文件,主要是傳它才使用FormData,否則不用這麼麻煩 form_data.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val()) $.ajax({ url:"", type:"post", contentType:false, //必須設置這兩個值 processData:false, data:form_data, //最後把這個對象傳給data success:function (data) { console.log(data) } }) })
局部鉤子
在規則裏面class 添加一個方法"clean_%s"name
def clean_tel(self): val = self.cleaned_data.get('tel') if len(val) == 11: return val else: raise ValidationError("手機號格式錯誤")
form.is_valid--》self.errors-->self.full_clean--》self._clean_fields()
依次校驗每一個字段,以後再走鉤子去判斷裏面有沒有clean_%s 用戶自定義的方法
if hasattr(self, 'clean_%s' % name): value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value
全局鉤子
def clean(self): pwd = self.cleaned_data.get('pwd') r_pwd = self.cleaned_data.get('r_pwd') if pwd and r_pwd: if pwd == r_pwd: return self.cleaned_data else: raise ValidationError('兩次密碼不一致!') else: return self.cleaned_data
視圖函數 form_test.html
<div class="container"> <form action="" method="post"> {% csrf_token %} <div class="row"> <div> <p> {{ form.name.label }}{{ form.name }}<span>{{ form.name.errors }}</span><span class="has-error pull-right">{{ errors.0 }}</span> #errors類 本身寫 </p> </div> <div> <p> {{ form.pwd.label }}{{ form.pwd }}<span>{{ form.pwd.errors }}</span> </p> </div> <div> <p> {{ form.r_pwd.label }}{{ form.r_pwd }}<span>{{ form.r_pwd.errors }}</span><span class="pull-right error">{{ errors.0 }}</span> </p> </div> <div> <p> {{ form.email.label }}{{ form.email }}<span>{{ form.email.errors }}</span> </p> </div> <div> <p> {{ form.tel.label }}{{ form.tel }}<span>{{ form.tel.errors }}</span> </p> </div> <input type="submit" value="提交">
cookie:具體一個瀏覽器針對一個服務器存儲key-value({})
獲取cookie:
cookie 信息儲存在request.COOKIE