Django 千鋒培訓的學習筆記(2)


Django 千鋒培訓讀書筆記
https://www.bilibili.com/video/av17879644/?p=1





切換到創建項目的目錄  cd C:\Users\admin\Desktop\DjangoProject
創建名為project的項目命令  django-admin startproject project
            注:所有路徑不要有中文
            切換到目錄cd C:\Users\admin\Desktop\DjangoProject\project
目錄層級說明:manage.py  一個命令行工具,可以讓我們用多種方式對Django項目進行交互
             __init__.py 一個空文件,它告訴Python這個目錄應該被看做一個包
             settings.py 項目的配置文件(主要處理文件)
             urls.py     項目的url聲明 (主要處理文件)
             wsgi.py     項目與WSGI兼容的Web服務器入口
配置數據庫   Django默認使用SQLite數據庫
            在settings.py文件中通過DATABASES選項進行數據庫配置
配置MySQL    Python3.x中安裝的是PyMySQL
            在__init__.py文件中寫入兩行代碼import pymysql
                                        pymysql.install_as_MySQLdb()
    以數據庫sunck為例進行示范:對settings.py中的DATABASES進行設置
            DATABASES = {
                'default': {
                    'ENGINE': 'django.db.backends.mysql',
                    'NAME': "sunck",
                    'USER': "root",
                    'PASSWORD': "admin123",
                    'HOST': "localhost",
                    'PORT': "3306"
                }
            }
創建應用--在一個項目中可以創建多個應用,每個應用進行一種業務處理
        打開CMD,進入project(目錄名)的目錄下,輸入命令創建名為myApp的app:
            python manage.py startapp myAPP
myAPP目錄說明
    admin.py    進行站點配置
    models.py   創建模型
    views.py    創建視圖
激活應用  在settings.py文件中,將myApp應用加入到INSTALLED_APPS選項中
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'myApp',
    ]
定義模型 概述:有一個數據表就對應有一個模型
        在models.py文件中定義模型
            引入:from django.db import models
            模型類要繼承models.Model類
            示例:
                class Grades(models.Model):
                    gname = models.CharField(max_length=20)
                    gdate = models.DateTimeField()
                    ggirlnum = models.IntegerField()
                    gboynum = models.IntegerField()
                    isDelete = models.BooleanField(default=False)

                class Students(models.Model):
                    sname = models.CharField(max_length=20)
                    sgender = models.BooleanField(default=True)
                    sage = models.IntegerField()
                    scontend = models.CharField(max_length=20)
                    isDelete = models.BooleanField(default=False)
                    sgrade = models.ForeignKey("Grades", on_delete=models.CASCADE,)
            說明:
                不需要定義主鍵,在生成時自動添加,並且值為自動增加
在數據庫中生成數據表
    生成遷移文件
        執行 python manage.py makemigrations    在migrations目錄下生成一個遷移文件,此時數據庫中還沒有生成數據表
    執行遷移
        執行 python manage.py migrate           相當於執行MySQL語句創建了數據表

測試數據操作
進入到python shell
    執行 python manage.py shell
引入包
    from myApp.models import Grades, Students
    from django.utils import timezone
    from datetime import *
查詢所有數據
    類名.objects.all()
    示例: Grades.objects.all()
添加數據
    本質:創建一個模型類的對象實例
    示例:CMD窗口下:
        grade1 = Grades()
        grade1.gname = "python04"
        grade1.gdate = datetime(year=2017, month=7, day=17)
        grade1.ggirlnum = 3
        grade1.gboynum = 70
        grade1.save()
查看某個對象
    類名.objects(pk=索引號)
    示例:
        Grades.objects.get(pk=2)
        Grades.objects.all()
修改某個數據
    模型對象屬性 = 新值
    示例:
        grade2.gboynum = 60
        grade2.save()
刪除數據
    模型對象.delete()
    grade2.delete()
    注意:這是物理刪除,數據庫中的相應數據被永久刪除
關聯對象
    示例:
        stu = Students()
        stu.sname = "Xue Yanmei"
        stu.sgender = False
        stu.sage = 20
        stu.scontend = "I am Xue Yanmei"
        stu.sgrade = grade1
        stu.save()
    獲得關聯對象的集合
        需求:獵取python04班級的所有學生
             對象名.關聯的類名小寫_set.all()
             示例:grade1.students_set.all()
        需求:創建曾志偉,屬於python04班級
            示例:
                stu3 = grade1.students_set.create(sname=u'Zhen Zhiwei',sgender=True,scontend=u"I am Zhen Zhiwei",sage=45)
            注意:這樣創建的數據直接被添加到了數據庫當中。
啟動服務器:
    格式:python manage.py runserver ip:port
    注意:ip可以不寫,不寫代表本機ip
    端口號默認是8000
    python manage.py runserver
    說明:
        這是一個純python編寫的輕量級web服務器,僅僅在開發測試中使用這個
Admin站點管理:
    概述:
        內容發布:負責添加,修改,刪除內容的
        公告訪問
    配置Admin應用:
        在settings.py文件中的INSTALLED_APPS中添加'django.contrib.admin',
        這條默認是添加好的。
    創建管理員用戶:
        在項目目錄下執行 python manage.py createsuperuser
        依次輸入賬號名,郵箱,密碼即可完成用戶創建
    登陸:
        http://127.0.0.1:8000/admin/
    漢化:
        把project\settings.py
        中作如下設定:LANGUAGE_CODE = 'zh-Hans'
                     TIME_ZONE = 'Asia/Shanghai'
管理數據表:
    修改 myAPP\admin.py 如下:
        from django.contrib import admin
        # Register your models here.
        from .models import Grades, Students
        # 注冊
        admin.site.register(Grades)
        admin.site.register(Students)
    自定義管理頁面:
        屬性說明
            # 列表頁屬性
            list_display = [] # 顯示字段設置
            list_filter = [] # 過濾字段設置
            search_fields = [] # 搜索字段設置
            list_per_page = [] # 分頁設置
            # 添加,修改頁屬性
            fields = [] # 規定屬性的先后順序
            fieldsets = [] # 給屬性分組 注意:fields與fieldsets不能同時使用
        屬性示例:
            # 列表頁屬性
            list_display = ['pk', 'gname', 'gdate', 'ggirlnum', 'gboynum', 'isDelete']
            list_filter = ['gname']
            search_fields = ['gname']
            list_per_page = 5
            # 添加,修改頁屬性
            # fields = ['ggirlnum', 'gboynum', 'gname', 'gdate', 'isDelete']
            fieldsets = [
                ("num",{"fields":['ggirlnum', 'gboynum']}),
                ("base", {"fields":["gname", "gdate", "isDelete"]}),
            ]
        關聯對象:需求:在創建一個班級時可以直接添加幾個學生
            class StudentsInfo(admin.TabularInline):# 可選參數admin.StackedInline
                model = Students
                extra = 2
            class GradesAdmin(admin.ModelAdmin):
                inlines = [StudentsInfo]
        布爾值顯示問題示例:
            class StudentsAdmin(admin.ModelAdmin):
                def gender(self):
                    if self.sgender:
                        return ""
                    else:
                        return ""
                # 設置頁面列的名稱
                gender.short_description = "性別"
                list_display = ['pk', 'sname', 'sage', gender,
                                'scontend', 'sgrade', 'isDelete']
                list_per_page = 10
            admin.site.register(Students, StudentsAdmin)
        執行按鈕位置:
            class StudentsAdmin(admin.ModelAdmin):
                ...snip...
                actions_on_top = False
                actions_on_bottom = True
            admin.site.register(Students, StudentsAdmin)
        使用裝飾器完成注冊:
            @admin.register(Students)
                class StudentsAdmin(admin.ModelAdmin):
                    def gender(self):
                    ...snip...
                    actions_on_top = False
                    actions_on_bottom = True
視圖的基本使用
    概述:
        在Django中,視圖是對web請求進行回應
        視圖就是一個python函數,在views.py文件中定義。
    定義視圖:
        示例:在myApp\views.py中寫入
            from django.shortcuts import render
            # Create your views here.
            from django.http import HttpResponse
            def index(request):
                return HttpResponse("Sunck is a good man")
    配置url:方法一:path方法:
        修改project目錄下的urls.py文件:
            from django.contrib import admin
            from django.urls import path, include
            urlpatterns = [
                path('admin/', admin.site.urls),
                path('', include('myApp.urls')),
            ]
        在myApp應用目錄下創建urls.py文件:
            from django.urls import path, include
            from . import views
            urlpatterns = [
                path('',views.index),
            ]
    配置url:方法二:url方法:
        修改project目錄下的urls.py文件:
            from django.contrib import admin
            from django.conf.urls import url,include
            urlpatterns = [
                url(r'^admin/', admin.site.urls),
                url(r'^', include('myApp.urls')),
            ]
        在myApp應用目錄下創建urls.py文件:
            from django.conf.urls import url
            from . import views
            urlpatterns = [
                url(r'^$', views.index),
            ]
模板的基本使用:
    概述:模板是HTML頁面,可以根據視圖中傳遞過來的數據進行填充
    創建模板:
        創建templates目錄,在目錄下創建對應項目的模板目錄(project/templates/myApp)
    配置模板路徑:
        修改settings.py文件下的TEMPLATES下的'DIRS''DIRS': [os.path.join(BASE_DIR, 'templates')],
    定義grades.html與students.html模板:
        在templates\myApp\目錄下創建grades.html與students.html模板文件
        模板語法:
            {{輸出值,可以是變量,也可以是對象,屬性}}
            {%執行代碼段%}
    http://127.0.0.1:8000/grades
        寫grades.html模板:
            <!doctype html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport"
                      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
                <meta http-equiv="X-UA-Compatible" content="ie=edge">
                <title>班級信息</title>
            </head>
            <body>
                <h1>班級信息列表</h1>
                <ul>
                    <!--[python04, python05, python06]-->
                    {%for grade in grades%}
                    <li>
                        <a href="#">{{grade.gname}}</a>
                    </li>
                    {%endfor%}
                </ul>
            </body>
            </html>
        定義視圖:myApp\views.py
            from .models import Grades
            def grades(request):
                # 去模板里取數據
                gradesList = Grades.objects.all()
                # 將數據傳遞給模板,模板再渲染頁面,將渲染好的頁面返回給瀏覽器
                return render(request, 'myApp/grades.html', {"grades": gradesList})
        配置url:myApp\urls.py
        urlpatterns = [
            url(r'^$', views.index),
            url(r'^(\d+)/(\d+)$', views.detail),
            url(r'^grades/', views.grades)
        ]
    http://127.0.0.1:8000/students
        寫students.html模板
            <!doctype html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport"
                      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
                <meta http-equiv="X-UA-Compatible" content="ie=edge">
                <title>學生頁面</title>
            </head>
            <body>
                <h1>學生信息列表</h1>
                <ul>
                    {%for student in students%}
                    <li>
                        {{student.sname}}--{{student.scontend}}
                    </li>
                    {%endfor%}
                </ul>
            </body>
            </html>
        定義視圖:myApp\views.py
            from .models import Students
            def students(request):
                studentsList = Students.objects.all()
                return render(request, 'myApp/students.html', {"students": studentsList})
        配置url:myApp\urls.py
            urlpatterns = [
            url(r'^$', views.index),
            url(r'^(\d+)/(\d+)$', views.detail),
            url(r'^grades/', views.grades),
            url(r'^students/', views.students),
        ]
    需求:點擊班級,顯示對應班級的學生名字
        運行不正常https://www.bilibili.com/video/av17879644/?p=12






Django流程梳理
    創建工程:執行 django-admin startproject 工程名
    創建項目:執行 python manage.py startapp 項目名稱
    激活項目:修改 settings.py中的INSTALLED_APPS
    配置數據庫:
        修改__init__.py文件
        修改settings.py文件中的DATABASES
    創建模型類:在項目目錄下的models.py文件中創建
    生成遷移文件:執行python manage.py makemigrations
    執行遷移:執行python manage.py migrate
    配置站點:略
    創建模板目錄/項目模板目錄
    在settings.py中的TEMPLATES添加templates路徑
    在工程目錄下(project)修改urls.py
    在項目目錄下創建urls.py


使用他人Django代碼需要的簡易修改:
1.在settings.py中修改數據庫名
2.在settings.py中修改數據庫密碼
3.刪除由內向外文件(在對應目錄里鼠標右鍵刪除)
4.在數據庫中創建對應第一步的數據庫(自己在SQL中創建)
5.執行生成遷移文件
6.執行遷移
7.啟動服務
8.瀏覽器測試


Django模型
    Django對各種數據庫提供了很好的支持,Django為這些數據庫提供了統一的調用API
    我們可以根據不同的業務需求選擇不同的數據庫。
    配置數據庫
        修改工程目錄下的__init__.py文件
            import pymysql
            pymysql.install_ad_MySQLdb()
        修改settings.py文件中的DATABASES
    開發流程
        配置數據庫
        定義模型類:一個模型都在數據庫中對應一張數據庫表
        生成遷移文件
        執行遷移生成數據表
        使用模型類進行增刪改查
    ORM
        概述:對象-關系-映射
        任務:
            根據對象的類型生成表結構
            將對象,列表的操作轉換成SQL語句
            將SQL語句查詢到的結果轉換為對象,列表
        優點:
            極大的減輕了開發人員的工作量,不需要面對因數據庫的變更而修改代碼的問題
    定義模型
        模型,屬性,表,字段之間的關系
            一個模型類在數據庫中對應一張表,在模型類中定義的屬性,對應該模型對照表中的一個字段
        定義屬性:見下文
        創建模型類
        元選項
            在模型類中定義Meta類,用於設置元信息
            示例:
                class Meta:
                    db_table = "students"
                    ordering = ['id']
            db_table
                定義數據表名,推薦用小寫字母,數據表名默認為項目名小寫_類名小寫
            ordering
                對象的默認排序字段,獲取對象的列表時使用
                示例:
                    ordering['id'] id按升序排列
                    ordering['-id'] id按降序排列
                注意:排序會增加數據庫開銷
    模型成員
        類屬性
            隱藏類屬性objects:
                是Manager類型的一個對象,作用是與數據庫進行交互
                當定義模型類時沒有指定管理器,則Django為模型創建一個名為objects的管理器
            自定義管理器示例:
                定義stuObj管理器:
                    stuObj = models.Manager()
                當為模型指定模型管理器,Django就不再為模型類生成objects模型管理器了。
            自定義管理器Manager類
                模型管理器是Django的模型進行與數據庫交互的窗口,一個模型可以有多個模型管理器
                作用:
                    向管理器類中添加額外的方法
                    修改管理器返回的原始查詢集
                        通常會重寫get_queryset()方法
                代碼示例:
                    class StudentsManager(models.Manager):
                        def get_queryset(self):
                            return super(StudentsManger, self).get_queryset().filter(isDelete=False)

                    class Students(model.Moder):
                        # 自定義模型管理器
                        # 當自定義模型管理器,objects就不存在了
                        stuObj = models.Manger()
                        stuObj2 = StudentsManager()

        創建對象
            目的:向數據庫中添加數據
            當創建對象時,django不會對數據庫進行讀寫操作,當調用save()方法時才與數據庫交互,將對象保存在數據庫表中。
            注意:
                __init__方法已經在父類models.Model中使用,在自定義的模型中無法使用。
            方法:
                在模型類中增加一個類方法,示例如下:
                    class Students(model.Moder):
                        ...snip...
                         @classmethod
                        def createStudent(cls, name, age, gender, contend,
                                          grade,lastT, createT, isD=False):
                            stu = cls(sname=name, sage=age, sgender=gender,
                                        scontend=contend, sgrade=grade, lastTime=lastT, createTime=createT,
                                        isDelete=isD)
                            return stu
                在自定義管理器中添加一個方法,示例如下:
                    class StudentsManager(models.Manager):
                        def get_queryset(self):
                            return super(StudentsManager, self).get_queryset().filter(isDelete=False)
                        def createStudent(self, name, age, gender, contend, grade, lastT, createT, isD=False):
                            stu = self.model()
                            # print(type(grade))
                            stu.sname = name
                            stu.sage = age
                            stu.sgender = gender
                            stu.scontend = contend
                            stu.sgrade = grade
                            stu.lastTime = lastT
                            stu.createTime = createT
                            return stu
        模型查詢
            概述
                查詢集表示從數據庫獲取的對象的集合
                查詢集可以有多個過濾器
                過濾器就是一個函數,基於所給的參數限制查詢集結果
                從SQL角度來說,查詢集和select語句等價,過濾器就像where條件
            查詢集
                在管理器上調用過濾器方法返回查詢集
                查詢集經過過濾器篩選后返回新的查詢集,所以可以寫成鏈式調用
                惰性執行
                    創建查詢集不會帶來任何數據庫的訪問,直到調用數據庫時,才會訪問數據
                直接訪問數據的情況:
                    迭代
                    序列化
                    與if合用
                返回查詢集的方法稱為過濾器
                    all():返回查詢集中的所有數據
                    filter():保留符合條件的數據
                        filter(鍵=值)
                        filter(鍵=值,鍵=值)
                        filter(鍵=值).filter(鍵=值)   且的關系
                    exclude():過濾掉符合條件的
                    order_by():排序
                    values():一條數據就是一個字典,返回一個列表
                    get()
                        返回一個滿足條件的對象
                        注意:
                            如果沒有找到符合條件的對象,會引發模型類.DoesNotExist異常
                            如果找到多個對象,會引發模型類MultipleObjectsReturned異常
                    count():返回查詢集中對象的個數
                    first():返回查詢集中第一個對象
                    last():返回查詢集中最后一個對象
                    exits():判斷查詢集中是否有數據,如果有數據返回 True,否則返回 False.
                限制查詢集
                    查詢集返回列表,可以使用下標的方法進行限制,等同於sql中的limit語句
                    注意:下標不能是負數
                    示例:studentsList = Students.stuObj2.all()[0:5]
                查詢集的緩存
                    概述:
                        每個查詢集都包含一個緩存,來最小化對數據庫的訪問
                        在新建的查詢集中,緩存首次為空,第一次對查詢集求值,會發生數據緩存,Django會將查詢出來的數據做一個緩存,並返回查詢結果。
                        以后的查詢直接使用查詢集的緩存
                字段查詢
                    概述
                        實現了sql中的where語句,作為方法filter(),exclude(),get()的參數
                        語法:屬性名稱__比較運算符=值
                        外鍵:屬性名稱_id
                        轉義:類似sql中的like語句
                             like有關情況看我哥他%是為了匹配點位,匹配數據中的%使用(where like "\%")
                             filter(sname__contains="%")
                    比較運算符
                        exact:判斷,大小寫敏感
                            filter(isDelete=False)
                        contains:是否包含,大小寫敏感
                            studentsList = Students.stuObj2.filter(sname__contains="")
                        startswith,endswith:以value開頭或結尾,大小寫敏感
                        以上四個在前面加上i,就表示不區分大小寫iexact,icontains,istartswith,iendswith
                        isnull,isnotnull
                            是否為空
                            filter(sname__isnull=False)
                        in:是否包含在范圍內
                        gt大於,gte大於等於,lt小於,lte小於等於
                        year,month,day,week_day,hour,minute,second
                            studentsList = Students.stuObj2.filter(lastTime__year=2017)
                        跨關聯查詢
                            處理join查詢
                                語法:
                                    模型類名__屬性名__比較運算符
                                    # 描述中帶有‘薛延美’這三個字的數據是屬於哪個班級的
                                    grade = Grades.objects.filter(students__scontend__contains='薛延美')
                                    print(grade)
                            查詢快捷pk代表的主鍵
                        聚合函數
                            使用aggregate函數返回聚合函數的值
                            Avg
                            Count
                            Max
                                maxAge = Student.stuObj2.aggregate(Max('sage'))
                                maxAge為最大的sage。
                            Min
                            Sum
                        F對象
                            可以使用模型的A屬性與B屬性進行比較
                            from django.db.models import F,Q
                            def grades1(request):
                                g = Grades.objects.filter(ggirlnum__gt=F('gboynum'))
                                print(g)
                                # [<Grades: python02>,<Grades: python03>]
                                return HttpResponse("OOOOOOOo")
                            支持F對象的算術運算
                                g = Grades.objects.filter(ggirlnum__gt=F('gboynum')+20)
                        Q對象
                            概述:過濾器的方法的關鍵字參數,條件為And模式
                            需求:進行or查詢
                            解決:使用Q對象
                                def students4(request):
                                    studentsList = Students.stuObj2.filter(Q(pk__lte=3) | Q(sage__gt=50))
                                    return render(request, 'myApp/students.html', {"students": studentsList})
                                只有一個Q對象的時候,就是用於正常匹配條件
                                studentsList = Students.stuObj2.filter(~Q(pk__lte=3))
                                ~Q是取反


定義屬性
    概述:
        django根據屬性的類型確定以下信息
            當前選擇的數據庫支持字段的類型
            渲染管理表單時使用的默認html控件
            在管理站點最低限度的驗證

        django會為表增加自動增長的主鍵列,每個模型只能有一個主鍵列,如
        果使用選項設置某屬性為主鍵列后,則django不會再生成默認的主鍵列

        屬性命名限制
            遵循標識符規則,且變量不能與Python保留字相同
            由於django的查詢方式,不允許使用連續的下划線

    庫
        定義屬性時,需要字段類型,字段類型被定義在django.db.models.fields目錄下,
        為了方便使用,被導入到django.db.models中

        使用方式
            導入: from django.db import models
            通過 models.Field創建字段類型的對象,賦值給屬性

    邏輯刪除
        對於重要類型都做邏輯刪除,不做物理刪除,實現方法是定義idDelete屬性,
        類型為BooleanField,默認值為False

    字段類型
        autoField
            一個根據實際ID自動增長的IntegerField,通常不指定,
            如果不指定,一個主鍵字段將自動添加到模型中

        CharField(max_length=字符長度)
            字符串,默認的表彰樣式是TextInput

        TextField
            大文本字段,一般超過4000時使用,默認的表單控件是Textarea

        IntegerField
            整數

        DecimalField(max_digits=None, decimal_places=None)
            使用Python的Decimal實例表示的十進制浮點數
            參數說明
                DecimalField.max_digits
                    位數總數
                DecimalField.decimal_places
                    小數點后的數字位置

        FloatField
            使用Python的float實例來表示的浮點數

        BooleanField
            True/False 字段,此字段的默認表彰控制是CheckboxInput

        NullBooleanField
            支持 Null, True, False 三種值

        DateField([auto_now=False, auto_now_add=False])
            使用Python的datetime.date實例表示的日期
            參數說明:
                DateField.auto_now
                    每次保存對象時,自動設置該字段為當前時間,用於“最后一次修改”
                    的時間戳,它總是使用當前日期,默認為 False
                DateField.auto_now_add
                    當前對象第一次被創建時自動設置當前時間,用於創建的時間戳,
                    它總是使用當前日期,默認為 False
            說明
                該字段默認對應的表單控件是一個TextInput.在管理員站點添加了一個
                JavaScript寫的日歷控件,和一個“Today”的快捷按鈕,包含了一個額外
                的invalid_date錯誤消息鍵
            注意
                auto_now_add, auto_now, and default 這些設置是相互排斥的,他們之間
                的任何組合將會發生錯誤的結果

        TimeField
            使用Python的datetime.time實例表示的時間,參數同DateField

        DateTimeField
            使用Python的datetime
            datetime實例表示的日期和時間,參數同DateField

        FileField
            一個上傳文件的字段

        ImageField
            繼承了FileField的所有屬性和方法,但對上傳的對象進行校驗,
            確保它是一個有效的image

    字段選項
        概述
            通過字段選項,可以實現對字段的約束
            在字段對象中通過關鍵字參數指定

        null
            如果為True,Django將空值以NULL存儲在數據庫中,默認值為 False

        blanke
            如果為True,則該字段允許為空白,默認值為 False

        注意
            null是數據庫范疇的概念,blank是表彰驗證范疇的概念

        db_column
            字段的名稱,如果未指定,則使用屬性的名稱

        db_index
            若值為 True,則在表中會為此字段創建索引

        default
            默認值

        primary_key
            若為 True,則該字段會成為模型的主鍵字段

        unique
            如果為 True,這個字段在表中必須有唯一值

    關系
        分類
            ForeignKey:一對多,將字段定義在多的端中
            ManyToManyField:多對多,將字段定義在兩端中
            OneToOneField:一對一,將字段定義在任意一端中

        用一訪問多
            格式
                對象.模型類小寫_set
            示例
                grade.students_set

        用一訪問一
            格式
                對象.模型類小寫
            示例
                grade.studnets

        訪問id
            格式
                對象.屬性_id
            示例
                student.sgrade_id


視圖
    概述:
        作用:視圖接收web請求,並響應web請求
        本質:視圖就是python中的一個函數
        響應:
            響應過程:
                用戶在瀏覽器中輸入網址www.sunck.wang/sunck/index.html
                ---網址--->
                django獲取網址信息,去掉IP與端口號,網址變成:sunck/index.html
                ---虛擬路徑與文件名--->
                url管理器逐個匹配urlconf,記錄視圖函數
                ---視圖函數名--->
                視圖管理,找到對應的視圖去執行,返回結果給瀏覽器
                ---響應的數據--->
                返回第一步:用戶在瀏覽器中輸入網址
            網頁
                重定向
                錯誤視圖
                    404視圖:找不到網頁(url匹配不成功時返回)時返回
                        在templates目錄下定義404.html
                            <!doctype html>
                            <html lang="en">
                            <head>
                                <meta charset="UTF-8">
                                <meta name="viewport"
                                      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
                                <meta http-equiv="X-UA-Compatible" content="ie=edge">
                                <title>Document</title>
                            </head>
                            <body>
                                <h1>頁面丟失</h1>
                                <h2>{{request_path}}</h2>
                            </body>
                            </html>
                            request_path:導致錯誤的網址
                        配置settings.py
                            DEBUG
                                如果為 True,永遠不會調用404頁面,需要調整為 False 才會顯示
                            ALLOWED_HOSTS = ['*']
                    500視圖:在視圖代碼中出現錯誤(服務器代碼錯誤)
                    400視圖:錯誤出現在客戶的操作
            JSON數據
    url配置
        配置流程:
            制定根級url配置文件
                settings.py文件中的ROOT_URLCONF
                ROOT_URLCONF = 'project.urls'
                默認實現了
            urlpatterns
                一個url實例的列表
                url對象
                    正則表達式
                    視圖名稱
                    名稱
            url匹配正則的注意事項
                如果想要從url中獲取一個值,需要對正則加小括號
                匹配正則前方不需要加'/'
                正則前需要加'r'表示字符串不轉義
        引入其他url配置
            在應用中創建urls.py文件,定義本應用的url配置,在工程urls.py中使用include方法
                project\urls.py
                from django.contrib import admin
                from django.conf.urls import url,include
                urlpatterns = [
                    url(r'^admin/', admin.site.urls),
                    url(r'^', include('myApp.urls', namespace="myAPP")),
                ]
                myApp\urls.py
                from django.urls import path, include
                from django.conf.urls import url
                from . import views
                urlpatterns = [
                    url(r'^$', views.index, name="index"),
                ]
        url的反向解析
            概述:如果在視圖,模板中使用了硬編碼鏈接,在url配置發生改變時,動態生成鏈接的地址
            解決:在使用鏈接時,通過url配置的名稱,動態生成url地址
            作用:使用url模板
    視圖函數
        定義視圖:
            本質:一個函數
            視圖參數:
                一個HttpRequest的實例
                通過正則表達式獲取的參數
            位置:一般在views.py文件下定義
    HttpRequest對象
        概述:
            服務器接收http請求后,會根據報文創建HttpRequest對象
            視圖的第一個參數就是HttpRequest對象
            django創建的,之后調用視圖時傳遞給視圖
        屬性
            path:請求的完整路徑(不包括域名和端口)
            method:表示請求的方式,常用的有GET,POST
            encoding:表示瀏覽器提交的數據的編碼方式,一般為utf-8
            GET:類似於字典的對象,包含了get請求的所有參數
            POST:類似於字典的對象,包含了post請求的所有參數
            FILES:類似字典的對象,包含了所有上傳的文件
            COOKIES:字典,包含所有的cookie
            session:類似字典的對象,表示當前會話
        方法
            is_ajax():如果是通過XMLHttpRequest發起的,返回 True
        QueryDict對象
            request對象中的GET,POST都屬於QueryDict對象
            方法:
                get():
                    根據鍵獲取值,只能獲取一個值
                    www.sunck.wang/abc?a=1&b=2&c=3
                getlist()
                    將鍵的值以列表的形式返回
                    可以獲取多個值
                    www.sunck.wang/abc?a=1&b=2&c=3
        GET屬性
            獲取瀏覽器傳遞過來數據
            www.sunck.wang/abc?a=1&b=2&c=3
            urls.py
            url(r'^get1', views.get1),   #結尾不能加$,否則無法匹配
            views.py
            def get1(request):
                a = request.GET.get('a')
                b = request.GET.get('b')
                c = request.GET.get('c')
                return HttpResponse(a + " " + b + " " + c)

            www.sunck.wang/abc?a=1&a=2&c=3
            urls.py
            url(r'^get2', views.get2),
            views.py
            def get2(request):
                a = request.GET.getlist('a')
                a1 = a[0]
                a2 = a[1]
                c = request.GET.get('c')
                return HttpResponse(a1 + " " + a2 + " " + c)
        POST屬性
            使用表單模擬POST請求
            關閉CSRF:project\project\settings.py
                MIDDLEWARE = [
                    'django.middleware.security.SecurityMiddleware',
                    'django.contrib.sessions.middleware.SessionMiddleware',
                    'django.middleware.common.CommonMiddleware',
                    # 'django.middleware.csrf.CsrfViewMiddleware',
                    'django.contrib.auth.middleware.AuthenticationMiddleware',
                    'django.contrib.messages.middleware.MessageMiddleware',
                    'django.middleware.clickjacking.XFrameOptionsMiddleware',
                ]
            示例:
                def showregist(request):
                    return render(request, 'myApp/regist.html',)

                def regist(request):
                    name = request.POST.get("name")
                    gender = request.POST.get("gender")
                    age = request.POST.get("age")
                    hobby = request.POST.getlist("hobby")
                    print(name)
                    print(gender)
                    print(age)
                    print(hobby)
                    return HttpResponse("regist")
            路徑:
                url(r'^showregist/$', views.showregist),
                    url(r'^showregist/regist/$', views.regist),
            頁面:
                   <!doctype html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <meta name="viewport"
                          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
                    <meta http-equiv="X-UA-Compatible" content="ie=edge">
                    <title>注冊</title>
                </head>
                <body>
                    <form action="regist/" method="post">
                        姓名:<input type="text" name="name" value=""/>
                        <hr>
                        性別:<input type="radio" name="gender" value="1">男<input type="radio" name="gender" value="0"><hr>
                        愛好:<input type="checkbox" name="hobby" value="power"/>權利<input type="checkbox" name="hobby" value="money">金錢<input type="checkbox" name="hobby" value="beauty">美女<input type="checkbox" name="hobby" value="Tesla">Tesla
                        <hr>
                        <input type="submit" value="注冊">
                    </form>
                </body>
                </html>
    HttpResponse對象
        概述:
            作用:給瀏覽器返回數據
            HttpRequest對象是由Django創建的,HttpResponse對象是由程序員創建
        用法:
            不用模板,直接返回數據
                語句示例:return HttpResponse("Sunck is a good man")
            調用模板
                使用render方法
                    原型:render(request, templateName[, context])
                    作用:結合數據和模板,返回一個完整的HTML頁面
                    參數:
                        request:請求體對象
                        templateName:模板路徑
                        context:傳遞給需要渲染在模板上的數據
        屬性
            content:表示返回內容
            charset:編碼格式
            status_code:響應狀態碼
                200
                304
                404
                400
            content-type:指定輸出的MIME類型
        方法
            init:使用頁面內容實例化HttpResponse對象
            write(content):以文件的形式寫入
            flush():以文件的形式輸出緩沖區
            set_cookie(key, value, maxAge=None, exprise=None)
            delete_cookie(key):
                刪除cookie
                如果刪除一個不存在的cookie,就當什么都沒發生
        子類HttpResponseRedirect
            功能:重定向,服務器端的跳轉
            簡寫
                redirect(to)
            to推薦使用反向解析
            示例:
                from django.http import HttpResponseRedirect
                from django.shortcuts import redirect
                def redirect1(request):
                    # return HttpResponseRedirect('/redirect2')
                    return redirect('/redirect2')
                def redirect2(request):
                    return HttpResponse("我是重定向后的視圖")
        子類JsonResponse
            返回Json數據,一般用於異步請求
            __init__(self.data)
            data 字典
            注意:Content-type類型為application/json
    狀態保持
        http協議是無狀態的,每次請求都是一次新的請求,它不記得之前的請求。
        客戶端與服務器的一次通信就是一次會話
        實現狀態的保持,在客戶端或服務端存儲有關會話的數據
        存儲的方式
            cookie:所有數據存儲在客戶端,不要存儲敏感的數據
            session:所有的數據存儲在服務端,在客戶端用cookie存儲session_id
        狀態保持的目的:
            在一段時間內跟蹤請求者的狀態,可以實現跨頁面訪問當前的請求者的數據
        注意:不同的請求者之間不會共享這個數據,與請求者一一對應
        啟用session:project\project\settings.py
            INSTALLED_APPS    'django.contrib.sessions',
            MIDDLEWARE    'django.contrib.sessions.middleware.SessionMiddleware',
        使用session
            啟用session后,每個httpRequest對象都有一個session屬性
            get[key, default=None]    根據鍵獲取session值
            clear()    清空所有會話
            flush()    刪除當前會話並刪除會話的cookie
            示例:
                # session
                def main(request):
                    # 取session
                    username = request.session.get('name', '游客')
                    print(username)
                    return render(request, 'myApp/main.html', {'username': username})

                def login(request):
                    return render(request, 'myApp/login.html')

                def showmain(request):
                    print("*****************")
                    username = request.POST.get('username')
                    # 存儲session
                    request.session['name'] = username
                    return redirect('/main/')

                from django.contrib.auth import logout
                def quit(request):
                    # 清除session
                    logout(request) # 方法1,推薦
                    # request.session.clear() # 方法2
                    request.session.flush() # 方法3
                    return redirect('/main/')
        設置session過期時間
            set_expiry(value)
            request.session.set_expiry(10)  設置為10秒后過期
            如果不設置,2個星期后過期
            value設置為0代表關閉瀏覽器時過期
            value設置為None代表設置永不過期,不推薦



Redis使用:略

************************************************************************************************************
****************************************第二篇筆記從這里開始************************************************
************************************************************************************************************

模板
    定義模板
        變量
            變量傳遞給模板的數據
            要遵守標識符規則
            語法 {{ var }}
            注意:如果使用的變量不存在,則插入的是空字符串
            在模板中使用點語法
                字典查詢
                屬性或者方法
                數字索引
            在模板中調用對象的方法
                注意:在模板里定義的函數不能傳遞self以外的參數
        標簽:語法   {% tag %}
            作用
                在輸出中創建文本
                控制邏輯和循環
        標簽示例:    
            if 格式 
                    {% if 表達式 %}
                        語句
                    {% endif %}
            if-else 格式   
                        {% if 表達式 %}
                            語句1
                        {% else %}
                            語句else
                        {% endif %}
            if-elif-else 格式 
                        {% if 表達式 %}
                            語句1
                        {% elif 表達式 %}
                            語句2
                        ...

                        {% else %}
                            語句else
                        {% endif %}
            for 格式
                    {% for 變量 in 列表 %}
                        語句
                    {% endfor %}
                格式2
                    {% for 變量 in 列表 %}
                        語句
                    {% empty %}  # 注意:列表為空或者列表不存在時執行語句2
                        語句2
                    {% endfor %}
                格式3
                    {{ forloop.counter }}
                示例:
                    <ul>
                        {% for stu in students %}
                            <li>
                                {{forloop.counter}}--{{stu.sname}}--{{stu.sgrade}}
                            </li>
                        {% empty %}
                            <li>目前沒有學生</li>
                        {% endfor %}
            commnet 格式
                {% commnet %}
                    被注釋的內容
                {% endcomment %}
                作用:相當於多行注釋,被注釋的內容不再執行
            ifequal/ifnotequal 作用 判斷是否相等或者不相等
                格式
                    {% ifequal 值1 值2 %}
                        語句1
                    {% endifequal %}  # 如果值1等於值2,執行語句1,否則不執行語句1
            include
                作用:加載模板並以標簽內的參數渲染
                格式:{% include '模板目錄' 參數1 參數2 %}
            url
                作用:反射解析
                格式:{% url 'namespace: name' p1 p2 %}
            csrf_token
                作用:用於跨站請求偽造保護
                格式:{% csrf_token %}
            block, extends
                作用:用於模板的繼承
            autoescape
                作用:用於HTML轉義
        過濾器
            語法 {{ var|過濾器 }}
            作用:在變量被顯示前修改它,只是加一個效果,對變量不會造成影響
            示例:
                lower
                upper
            過濾器可以傳遞參數,參數用引號引起來
                join 格式 列表|join:"#"
                     示例:{{list1|join:"#"}}
            如果一個變量沒有被提供,或者值為false,空,我們可以通過 default 語法使用默認值
                格式: {{str1|default:"沒有"}}
            根據給定格式轉換日期為字符串:date
                格式: {{dateVal|date:'y-m-d'}}
            HTML轉義:escape
            加減乘除示例:
                <h1>num = {{num|add:10}}</h1>
                <h1>num = {{num|add:-10}}</h1>
                <h1>num = {% num widthratio num 1 5%}</h1>
                <h1>num = {% num widthratio num 5 1%}</h1>
        注釋
            單行注釋:語法: {# 被注釋的內容 #}
            多行注釋
                {% commnet %}
                    被注釋的內容
                {% endcomment %}

    反射解析
        示例:
            project/project/urls.py
            url(r'^', include('myApp.urls', namespace='app')),
            project/myApp/urls.py
            url(r'^good/(\d+)$', views.good, name="good")
            templates/good.html
            <a href={% url 'app:good' 1 %}>鏈接</a>

    模板繼承
        作用:模板繼承可以減少頁面的重復定義,實現頁面的重用
        block標簽:在父模板中預留區域 ,子模板去填充
            語法 : {% block 標簽名 %}

                    {% endblock 標簽名 %}
        extends標簽:繼承模板,需要寫在模板文件的第一行
            語法 : {% extends 'myApp/base.html' %}
                    {% block main %}
                        內容
                    {% endblock 標簽名 %}
        示例:
            定義父模板
                body標簽中
                {% block main %}
                        
                {% endblock main %}

                {% block main %}
                        
                {% endblock main2 %}
            定義子模板
                {% extends 'myApp/base.html' %}
                {% block main %}
                    <h1>sunck is a good man</h1>
                {% endblock main %}

                {% block main2 %}
                    <h1>kaige is a good man</h1>
                {% endblock main2 %}

    HTML轉義
        問題:return render(request, 'myApp/index.html', {"code": "<h1>sunck is a very good man</h1>"})中的{{code}}
              {{code}}里的code被當作<h1>sunck is a very good man</h1>顯示,未經過渲染
        解決方法:
            {{code|safe}}
        或  {% autoescape off %}
                {{code}}
            {% endautoescape %}  # 這個可以一口氣解決一堆

    CSRF:
    跨站請求偽造
        某些惡意網站包含鏈接,表單,按鈕,js,利用登錄用戶在瀏覽器中認證,從而攻擊服務
    防止CSRF
        在settings.py文件的MIDDLEWARE增加'django.middleware.csrf.CsrfViewMiddleware'
        {% csrf_token %}        

    驗證碼
        作用
            在用戶注冊,登錄頁面的時候使用,為了防止暴力請求,減輕服務器的壓力
            是防止CSRF的一種方式

    驗證碼代碼示例:
寫在views.py里面
=================================================================================================
def verifycode(request):
    # 引入繪圖模塊
    from PIL import Image, ImageDraw, ImageFont
    # 引入隨機函數模塊
    import random
    # 定義變量,用於畫面的背景色,寬,高
    bgcolor = (random.randrange(20, 100), random.randrange(20, 100), random.randrange(20, 100))
    width = 100
    height = 50
    # 創建畫面對象
    im = Image.new('RGB', (width, height), bgcolor)
    # 創建畫面對象
    draw = ImageDraw.Draw(im)
    # 調用畫筆的point()函數繪制噪點
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill=fill)
    # 定義驗證碼的備選值
    str = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'
    # 隨機選取4個值作為驗證碼
    rand_str = ''
    for i in range(0, 4):
        rand_str += str[random.randrange(0, len(str))]
    # 構造字體對象
    font = ImageFont.truetype(r'C:\Windows\Fonts\AdobeArabic-Bold.otf', 40)
    # 構造字體顏色
    fontcolor1 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor2 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor3 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor4 = (255, random.randrange(0, 255), random.randrange(0, 255))
    # 繪制4個字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor1)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor2)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor3)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor4)
    # 釋放畫筆 
    del draw
    # 存入session,用於做進一步的驗證
    request.session['verifycode'] = rand_str
    # 內存文件操作
    import io
    buf = io.BytesIO()
    # 將圖片保存在內存中,文件類型為png
    im.save(buf, 'png')
    # 將內存中的圖片數據返回給客戶端,MIME類型為圖片png
    return HttpResponse(buf.getvalue(), 'image/png')


from django.shortcuts import render, redirect
def verifycodefile(request):
    f = request.session["falg"]
    str = ""
    if f == False:
        str = "請重新輸入!"
    request.session.clear()
    return render(request, 'myApp/verifycodefile.html', {"flag":str})

def verifycodecheck(request):
    code1 = request.POST.get("verifycode").upper()
    code2 = request.session["verify"].upper()
    if code1 == code2:
        return render(request, 'myApp/success.html')
    else:
        request.session["flag"] = False
        return redirect('/verifycodefile')

==============================================================================
寫在verifycodefile.html的<body>標簽中
<body>
    <form method="post" action="/verifycodecheck/">
        {%csrf_token%}
        <input type="text" name="verifycode"/>
        <img src="/verifycode">
        <input type="submit" name="登錄">
        <span>{{flag}}</span>
    </form>
</body>

==============================================================================


Django高級擴展
    靜態文件
        css,js,圖片,json文件,字體文件等
        配置settings.py
            STATIC_URL = '/static'
            STATICFILES_DIRS = [
                os.path.join(BASE_DIR, 'static')
            ]

    中間件
        概述:一個輕量級,底層的插件,可以介入Django的請求和響應。
        本質:一個Python類
        方法:
            __init__ 
                不需要傳參數,服務器響應第一個請求的時候自動調用,用於確定是否啟用該中間件
            process_request(self, request) 
                在執行視圖之前被調用(分配url匹配視圖之前),每個請求都會調用,返回None或者HttpResponse對象
            process_view(self, request, view_func. view_args, view_kwargs)
                調用視圖之前執行,每個請求都會調用,返回None或者HttpResponse對象
            process_template_response(self, request, response)
                在視圖剛好執行完后調用,每個請求都會調用,返回None或者HttpResponse對象
                使用render
            process_response(self, request, response)
                所有響應返回瀏覽器之前調用,每個請求都會調用,返回HttpResponse對象
            process_exception(self, request, exception)
                當視圖拋出異常時調用,返回HttpResponse對象
        執行過程:
            __init__ --> process_request--> url --> process_view --> view --> process_template_response --> template --> process_response -->返回開頭部分
         執行位置:
        自定義中間件
            在工程目錄下的middleware目錄下創建myApp
            創建一個python文件
            from django.utils.deprecation import middlewareMixin
            class MyMiddle(middlewareMixin):
                def process_request(self, request):
                    print("get參數為: ", request.GET.get("a"))
        使用自定義中間件
            配置settings.py文件 在MIDDLEWARE中添加 'middleware.myApp.MyMiddle.MyMiddle',

    上傳圖片
        概述:
            文件上傳時,文件數據request.FILES屬性中.
            注意:form表單要上傳文件需要加enctype="multipart/form-data"
            注意:上傳文件必須用post請求
        存儲路徑:
            在static目錄下創建upfile目錄用於存儲上傳的文件
            配置settings.py文件 MDEIA_ROOT = os.path.join(BASE_DIR, r'static\upfile')

views.py內容
==============================================================================
def upfile(request):
    return render(request, 'myApp/upfile.html')

import os
from django.conf import settings
def savefile(request):
    if request.method == "POST":
        f = request.FILES["file"]
        # 文件在服務器端的路徑
        filePath = os.pasth.join(settings.MDEIA_ROOT, f.name)
        with open(filePath, 'wb') as fp:
            for info in f.chunks():
                fp.write(info)
        return HttpResponse("上傳成功。")
    else:
        return HttpResponse("上傳失敗。")
==============================================================================
upfile.html中<body>里的內容
<body>
    <form method="post" action="/savefile" enctype="multipart/form-data">
        {%csrf_token%}
        <input type="file" name="file"/>
        <input type="submit" value="上傳"/>
    </form>
</body>
==============================================================================

    分頁
        Paginator對象
            創建對象
                格式 Paginator(列表,整數)
                返回值 返回的分頁對象
            屬性
                count 對象總數
                num_pages 頁面總數
                page_range
                    頁碼列表
                    [1,2,3,4,5]
                    頁碼從1開始
            方法
                page(num) 獲得一個Page對象,如果提供的頁碼不存在會拋出"InvalidPage"異常
            異常
                InvalidPage:當向 page()傳遞的是一個無效的頁碼時拋出
                PageNotAnInteger:當向 page()傳遞的不是一個整數時拋出
                EmptyPage:當向 page()傳遞一個有效值,但是該頁面里沒有數據時拋出
        Page對象
            創建對象
                Paginator對象的 page()方法返回得到Page對象
                不需要手動創建
            屬性
                object_list:當前頁上所有數據(對象)列表
                number:當前頁面的頁碼值
                paginator:當前page對象關聯的paginator對象
            方法
                has_next() 判斷是否有下一頁,如果有返回 True
                has_previous() 判斷是否有上一頁,如果有返回 True
                has_other_pages() 判斷是否有上一頁或者下一頁,如果有返回 True
                next_page_number() 返回下一頁的頁碼,如果下一頁不存在拋出InvalidPage異常
                previous_page_number() 返回上一頁的頁碼,如果上一頁不存在,拋出InvalidPage異常
                len() 返回當前頁的數據(對象)個數

        Paginator與Page對象關系(略)
        代碼示例:
        配置路由:url(r'^studentpage/(\d+)/$', views.studentpage),
        配置視圖:
            from .models import Students
            from django.core.paginator import Paginator
            def studentpage(request, pageid):
                # 所有學生列表
                allList = Students.objects.all()
                paginator = Paginator(allList, 6)
                page = paginator.page(pageid)
                return render(request, 'myApp/studentpage.html', {"students": page})
        配置html
        studentpage.html中body標簽中的內容:
            <body>
                <ul>
                    {% for stu in students %}
                    <li>
                        {{stu.sname}}--{{stu.sgrade}}
                    </li>
                    {% endfor %}
                </ul>
                <ul>
                    {% for index in students.paginator.page_range %}
                        {% if index == students.number %}
                            <li>
                                {{index}}
                            </li>
                        {% else %}
                            <li>
                                <a href="/sunck/studentpage/{{index}}">{{index}}</a>
                            </li>
                        {% endif %}
                    {% endif%}
                </ul>
            </body>
==============================================================================

    ajax
        需要動態生成,請求JSON數據
    代碼示例
        ajaxstudents.html頁面示例
        <script type="text/javascript" src="/static/myApp/js/jquery-3.1.1.min.js"></script>
        <body>
            <h1>學生信息列表</h1>
            <button id="btn">顯示學生信息</button>
            <script type="text/javascript" src="/static/myApp/js/sunck.js"></script>
        </body>

        sunck.js代碼示例
        $(document).ready(function (){
            document.getElementById("btn").onclick = function (){
                $.ajax({
                    type:"get",
                    url:"/studentsinfo/",
                    dataType:"json",
                    success:function(data, status){
                        console.log(data)
                        var d = data["data"]
                        for(var i=0; i<d.length; i++){
                            document.write('<p>' + d[i][0] + '</p>')
                        }
                    }
                })
            }
        })

        views.py代碼示例
        def ajaxstudents(request):
            return render(request, 'myApp/ajaxstudents.html')

        from django.http import JsonResponse
        def studentsinfo(request):
            stus = Students.objects.all()
            list = []
            for stu in stus:
                list.append([stu.sname, stu.sage])
            return JsonResponse({"data":list})
==============================================================================

    富文本
        pip install django-tinymce
        在站點中使用
            配置settings.py文件
                INSTALLED_APPS 列表中添加 'tinymce',
                增加    
                    # 富文本
                    TINYMCE_DEFAULT_CONFIG = {
                        'theme':'advanced',
                        'width':600,
                        'height':400,
                    }
            創建一個模型類:
                在models.py文件中增加
                from tinymce.models import HTMLField
                class Text(models.Model):
                    str = HTMLField()
            配置站點:
                from .models import Text
                admin.site.register(Text)
        
        自定義視圖使用
            <head>
                <meta charset="UTF-8">
                <title>富文本</title>
                <script type="text/javascript" src="/static/tiny_mce/tiny_mce.js"></script>
                <script type="text/javascript">
                    tinyMCE.init({
                        'mode':'textareas',
                        'theme':'advanced',
                        'width':'800',
                        'height':'600',
                        })
                </script>
            </head>
            <body>
                <form action="/saveedit/" method="post">
                    <textarea name="str">sunck is a good man</textarea>
                    <input type="submit" value="提交"/>
                </form>
            </body>

        Celery
            http://docs.jinkan.org/docs/celery/
            問題:
                用戶發起request,並且要等待response返回,但在視圖中有一些耗時的操作,
                導致用戶可能會等待很長時間才能接收response,這樣用戶體驗很差
                網站每隔一段時間要同步一次數據,但是http請求是需要觸發的
            解決:
                celery來解決
                    將耗時的操作放在celery中執行
                    使用celery定時執行
            celery:
                任務task
                    本質是一個Python函數,將耗時的操作封裝成一個函數
                隊列queue
                    將要執行的任務放在隊列里
                工人worker
                    負責執行對列中的任務
                代理broker
                    負責高度,在部署環境中使用redis
            安裝:
                pip install celery
                pip install celery-with-redis
                pip install django-celery
            配置settings.py
                在INSTALLED_APPS 列表中添加 'djcelery',
                # Celery
                import djcelery
                djcelery.setup_loader() # 初始化
                BROKER_URL='redis://:sunck@127.0.0.1:6379/0'
                CELERY_IMPORTS=('myApp.task')
            在應用目錄下創建task.py文件
            遷移生成celery需要的數據庫表:python manage.py migrate
            在工程目錄下的project目錄下創建celery.py文件
                celery.py文件全部內容
                from __future__ import absolute_import

                import os
                from celery import Celery
                from django.conf import settings

                os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whthas_home.settings')

                app = Celery('portal')

                app.config_from_object('django.conf:settings')
                app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


                @app.task(bind=True)
                def debug_task(self):
                    print('request: {0!r}'.format(self.request))
            在工程目錄下的 project目錄下的 __init__.py文件中添加

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM