django基礎(chǔ)

django 就是一個(gè)后端的框架宅楞,每一個(gè)URL都對(duì)應(yīng)一個(gè)處理函數(shù)涩金,對(duì)應(yīng)關(guān)系存儲(chǔ)在 urls 文件中,
而處理函數(shù)放在 所建立的 APP 下的 views 文件內(nèi)啼器。
MVC框架
MVC框架的核心思想是:解耦拜马,讓不同的代碼塊之間降低耦合星持,增強(qiáng)代碼的可擴(kuò)展性和可移植性坛吁,實(shí)現(xiàn)向后兼容寇损。

Web MVC各部分的功能
M全拼為Model藻茂,主要封裝對(duì)數(shù)據(jù)庫(kù)層的訪問(wèn)驹暑,對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增、刪辨赐、改优俘、查操作。
V全拼為View掀序,用于封裝結(jié)果帆焕,生成頁(yè)面展示的html內(nèi)容。
C全拼為Controller不恭,用于接收請(qǐng)求叶雹,處理業(yè)務(wù)邏輯,與Model和View交互换吧,返回結(jié)果折晦。
創(chuàng)建項(xiàng)目的命令
django-admin startproject 項(xiàng)目名稱
例:django-admin startproject test1
基本目錄
C:.
│  manage.py
└─test1
        settings.py
        urls.py
        wsgi.py
        __init__.py

manage.py是項(xiàng)目管理文件,通過(guò)它管理項(xiàng)目沾瓦。
與項(xiàng)目同名的目錄满着,此處為test1。
_init_.py是一個(gè)空文件贯莺,作用是這個(gè)目錄test1可以被當(dāng)作包使用风喇。
settings.py是項(xiàng)目的整體配置文件。
urls.py是項(xiàng)目的URL配置文件乖篷。
wsgi.py是項(xiàng)目與WSGI兼容的Web服務(wù)器入口响驴。
創(chuàng)建應(yīng)用
使用一個(gè)應(yīng)用開發(fā)一個(gè)業(yè)務(wù)模塊,此處創(chuàng)建應(yīng)用名稱為booktest撕蔼,
創(chuàng)建應(yīng)用的命令如下:python manage.py startapp booktest
運(yùn)行服務(wù)器命令
python manage.py runserver ip:端口
例:python manage.py runserver
可以不寫IP和端口豁鲤,默認(rèn)IP是127.0.0.1秽誊,默認(rèn)端口為8000。
如果增加琳骡、修改锅论、刪除文件,服務(wù)器會(huì)自動(dòng)重啟楣号,按ctrl+c停止服務(wù)器最易。

初始化設(shè)置項(xiàng)目中文和中國(guó)時(shí)區(qū)

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-Hans'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
需要再 next\next 下的 setting 中注釋掉這句
'django.middleware.csrf.CsrfViewMiddleware'

mysite項(xiàng)目

建立的項(xiàng)目文件名稱為 mysite,app 為 blog
在 mysite/blog 下建立一個(gè)static炫狱,用來(lái)存放 js藻懒,image,jquery 等靜態(tài)文件视译,放入一個(gè)jquery
# setting 配置文件最后添加
STATIC_URL = '/static/' // 別名嬉荆,指代下面的 static

STATICFILES_DIRS=(
    os.path.join(BASE_DIR, 'blog' 'static'),
)
templates 存放html文件,引入 jquery酷含,需要在 html 中引入
{% load staticfiles %}
<script src="{% static 'jquery-3.3.1.min.js' %}"></script>

# 在瀏覽器端可以看到渲染之后的結(jié)果:
<script src="/static/jquery-3.3.1.min.js"></script>

# 一般引入模式
<script src="/static/jquery-3.3.1.min.js"></script>
blog 下的 urls 文件鄙早,這個(gè)文件的作用就是來(lái)存放 URL 與處理函數(shù)的關(guān)系
from django.contrib import admin
from django.urls import path
from blog import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('show_time/', views.show_time), //添加這一條
]
blog 下的 views 文件,存放處理函數(shù)
from django.shortcuts import render
import time
def show_time(request):
    # return HttpResponse("hello")
    return  render(request,"index.html",{"t":time.ctime()}) //返回一個(gè)時(shí)間
redirect 重定向椅亚,在函數(shù)的末尾返回一個(gè)重定向的網(wǎng)址限番,也就是使得django 返回執(zhí)行 login URL 對(duì)應(yīng)的函數(shù)
return  redirect("/login")
redirect 和 render 的區(qū)別:
用 render 代替 redirect 時(shí),URL 不會(huì)有變化呀舔,所以刷新之后還是會(huì)跳轉(zhuǎn)到原來(lái)的網(wǎng)址
(瀏覽器根本就不知道你現(xiàn)在的render后的網(wǎng)址弥虐,因?yàn)檫@個(gè)網(wǎng)頁(yè)是服務(wù)器發(fā)給瀏覽器的,
而不是瀏覽器用URL去請(qǐng)求的)
Template 模版
組成:HTML代碼+邏輯控制代碼
用 context 渲染 template 模版

在模版中媚赖,如果要調(diào)用從 context 中傳入的變量(變量不管是list躯舔,dict,class對(duì)象省古,日期,
等之類的都可以)丧失,需要用 dots  來(lái)調(diào)用值豺妓。

變量的過(guò)濾器 | (filter)

{{變量名}}
{%代碼段%}

標(biāo)簽:{% tags %}
if,endif 結(jié)尾
    {% if a > 200 %}
        <p style="color: red;">
    {% else %}
        <p>
    {% endif %}
    libai</p>

for 在 views 定義 test = [234,'works']
    <p> test: {{ test.0 | add:10 }} </p>
    <p> test: {{ test.1 | upper }} </p>
    {% for foo in test %}
        <p>{{ forloop.counter }} : {{ foo }}</p>
    {% endfor %}
  
輸出結(jié)果:
1 : 234
2 : works

extend 繼承模版布讹,可以減少大量 html 的重復(fù)代碼琳拭,建立一個(gè) base.html 作為模版,
在其他需要用到的html中直接引入即可描验,只修改需要改動(dòng)的地方白嘁。

sqlite 數(shù)據(jù)庫(kù)

pycharm 默認(rèn)連接的是sqlite數(shù)據(jù)庫(kù)

# 在 setting 中可以看到默認(rèn)的 databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# 在models文件中添加,創(chuàng)建一張表膘流,
class Book(models.Model):
    name = models.CharField(max_length=20)
    price = models.IntegerField()
    pub_data = models.DateField()

在命令行中輸入terminal中 :python manage.py makemigrations 創(chuàng)建表
                          python manage.py migrate

創(chuàng)建成功之后就可以在 pycharm 中連接 sqlite 數(shù)據(jù)庫(kù)了

連接上后就可以在視圖窗口中修改數(shù)據(jù)庫(kù)的數(shù)據(jù)了

note

表與表之間的關(guān)系(兩張表)
     一對(duì)多
     多對(duì)多
     一對(duì)一

單表操作  
        表記錄的添加
        方式一:
            Book()
            b=Book(name="python基礎(chǔ)",price=99,author="libai",pub_date="2017-12-12")
            b.save()
        方式二:
            Book.objects.create()
            Book.objects.create(name="老男孩linux",price=78,author="oldboy",pub_date="2016-12-12")

        表記錄的修改
        方式一:
            b=Book.objects.get(author="oldboy")
            b.price=120
            b.save()
        方式二:
            #update是QuerySet
            Book.objects.filter(author="yuan").update(price=999)
         
        表記錄的刪除:
            Book.objects.filter(author="oldboy").delete()
            
        表記錄的查詢:
                book_list = Book.objects.filter(id=2)
                book_list=Book.objects.exclude(author="yuan").values("name","price")
                book_list=Book.objects.all()
                book_list = Book.objects.all()[::2]
                book_list = Book.objects.all()[::-1]
                
                #first絮缅,last,get取到的是一個(gè)實(shí)例對(duì)象鲁沥,并非一個(gè)QuerySet的集合對(duì)象
                book_list = Book.objects.first()
                book_list = Book.objects.last()  
                book_list = Book.objects.get(id=2)#只能取出一條記錄時(shí)才不報(bào)錯(cuò)
                
                ret1=Book.objects.filter(author="oldboy").values("name") #只取出字段為name的值
                ret2=Book.objects.filter(author="yuan").values_list("name","price")           

                book_list= Book.objects.all().values("name").distinct()
                book_count= Book.objects.all().values("name").distinct().count()
               
                模糊查詢  雙下劃線__
                book_list=Book.objects.filter(name__icontains="P").values_list("name","price")
                book_list=Book.objects.filter(id__gt=5).values_list("name","price")
                
      多表操作(一對(duì)多):
               添加記錄
               #publish_id=2
               Book.objects.create(name="linux運(yùn)維",price=77,pub_date="2017-12-12",publish_id=2)
               
               #publish=object
               Book.objects.create(name="GO",price=23,pub_date="2017-05-12",publish=publish_obj)
               
               查詢記錄(通過(guò)對(duì)象)
                     正向查詢:
                     book_obj=Book.objects.get(name="python")   
                     pub_obj=book_obj.publish----》書籍對(duì)象對(duì)應(yīng)的出版社對(duì)象
                     pub_obj.name
                     反向查詢:
                     pub_obj = Publish.objects.filter(name="人民出版社")[0]
                     pub_obj.book_set.all().values("name","price")
                     
               查詢記錄(filter values  雙下劃線__)
                    人民出版社出版過(guò)的書籍與價(jià)格
                    ret=Book.objects.filter(publish__name="人民出版社").values("name","price")
                    python這本書出版社的名字
                    ret2=Publish.objects.filter(book__name="python").values("name")
                    python這本書出版社的名字
                    ret3=Book.objects.filter(name="python").values("publish__name")
                    北京的出版社出版書的名字
                    ret4=Book.objects.filter(publish__city="北京").values("name")
                    2017年上半年出版過(guò)書的出版社的名字
                    ret5=Book.objects.filter(pub_date__lt="2017-07-01",pub_date__gt="2017-01-01").values("publish__name")
                    
     多表操作(多對(duì)多): 
                創(chuàng)建多對(duì)多的關(guān)系 author= models.ManyToManyField("Author")
                書籍對(duì)象它的所有關(guān)聯(lián)作者  obj=book_obj.authors.all()
                   綁定多對(duì)多的關(guān)系  obj.add(*QuerySet)   
                                    obj.remove(author_obj)
                 
                如果想向第三張表插入值的方式綁定關(guān)系:  手動(dòng)創(chuàng)建第三張表
                    # class Book_Author(models.Model):
                    # book=models.ForeignKey("Book")
                    # author=models.ForeignKey("Author")                    
                    Book_Author.objects.create(book_id=2,author_id=3)


1.Cookie操作
    - 客戶端本地存儲(chǔ)的鍵值對(duì),每次請(qǐng)求瀏覽器都會(huì)帶上cookie去訪問(wèn)
    - 確認(rèn)身份
2.Session操作
    - 保存在服務(wù)器端的鍵值對(duì)耕魄,客戶端會(huì)獲得一個(gè)sessionid來(lái)標(biāo)識(shí)画恰,獲取數(shù)據(jù)
3.URL路由
    - /index    ->    views.函數(shù)

4.MTV

5.View中返回方式
    - HttpResponse("內(nèi)容")
    - render(request,'模版路徑',{ })
    - redirect('URL')
6.啟動(dòng)
    python manage.py runserver
7.創(chuàng)建project
    django-admin startproject [project名稱]
    python manage.py startapp [app名稱]
8.URL中有別名
    [
        ('/index/(\d+)', func, name='xxoo')
    ]
9.setting.py 配置
    STATICFILES_DIRS=(
        os.path.join(BASE_DIR,'static'),
    )
10.模版
    {{ 變量 }}
    {% for, if, %}

    views.py
        def func(request):
            return render(request, 'index.html',{'arg':[1,2,4,5,6]})
    index.html

    {{ arg.2 }} 取第三個(gè)元素

11.數(shù)據(jù)庫(kù)連接修改MySQL
    默認(rèn):MySQLDB
    python 3 要修改成pymysql

12.模版繼承
    block
    extends
    一個(gè)模版可以被多個(gè)子模版繼承

13.request參數(shù)
    - request.method
    - request.GET
    - request.POST.get
    - request.POST.getlist('hobby')

14.外鍵

15.操作數(shù)據(jù)表
    python manage.py makemigrations
    python manage.py migrate

16.在html中使用別名指代靜態(tài)文件路徑

17.路由分發(fā)

18.數(shù)據(jù)操作
    models.Tb.objects.all().delete()
    models.Tb.objects.filter(條件).delete()

19.外鍵的添加
    calss A(models.Model): 部門表
        name = c.CharField(max_length=16,null=True,blank=True)
        //black是admin里是否允許輸入為空
    class B():
        title = c
        fk = FK(A)
    models.B.object.create(
        title = '1',
        fk = models.A.object.get(id=1)
    )
    
    models.B.object.create(
        title = '1',
        fk_id = 1
    )   

20.外鍵關(guān)聯(lián)刪除

21.URL匹配
    [
        ('/index/(?P<nid>\d+)'),func
    ]
    views.py
        def func(request,nid):
            pass
22.ORM
    -Models中操作
    - shell操作

    對(duì)象 = models.Tb.object.get(id=1)
    [對(duì)象,] = models.Tb.object.filter(id=1)

23.CSRF

24.自定義標(biāo)簽

25.XSS攻擊

    views.py
        def func(request,nid):
            return render(request,'x.html',{'k1':'v1','k2':'<h1>v2</h1>'})
    x.html
        {{ k1 }}
        {{ k2 }}
        頁(yè)面輸出:
        v1
        <h1>v2</h1>
        
        {{ k1 }}
        {{ k2|safe }}
        頁(yè)面輸出:
        v1
        v2(加大加粗)

26.obj = models.Tb.objects.get(id=1)
   obj.name = '新名稱'
   obj.save()

   models.Tb.objects.filter(id=1).update(name="新名稱")

27.多表查詢 雙下劃線跨表查詢

28.URL,namespace

30.迭代器

31.數(shù)據(jù)傳遞中吸奴,來(lái)回的都是字符串


django 的請(qǐng)求生命周期
    也就是用戶從URL訪問(wèn)服務(wù)器后發(fā)生的一系列事件
    request.GET 就是在請(qǐng)求頭中的URL中獲取數(shù)據(jù)允扇,轉(zhuǎn)成字典形式
    request.POST 把請(qǐng)求體中的字符串轉(zhuǎn)換成字典

urls.py 文件的正則匹配,要加$完整匹配


-請(qǐng)求響應(yīng)Http
    1.發(fā)送Http請(qǐng)求
    2.服務(wù)器接收则奥,根據(jù)請(qǐng)求頭中的URL在路由關(guān)系表中進(jìn)行匹配(從上到下)
    3.匹配成功后考润,執(zhí)行指定的views函數(shù)
        URL -》 函數(shù)  ==》 FBV
        URL -》 類    ==》 CBV
  視圖函數(shù)可以用function,也可以用類方法來(lái)接收读处,使用類糊治,就要繼承django為我們提供的父類,URL路由導(dǎo)航也要有所更改
  #urls.py 中
    path('CBV/', views.CBV.as_view()),
  #views.py 中
from django.views import View
class CBV(View): // 繼承 View 后档泽,method為GET就會(huì)自動(dòng)調(diào)用get方法俊戳,post類似
    def get(self,request):
    根據(jù)請(qǐng)求頭中的 request.method 進(jìn)行自動(dòng)執(zhí)行
        return HttpResponse("CBV.get")
    def post(self,request):
        return HttpResponse("CBV.post")
  在父類 View 中封裝了dispatch方法,URL路由傳遞過(guò)來(lái)的URL和method首先會(huì)傳到dispatch中馆匿,
  用反射找到我們自定制的方法并執(zhí)行抑胎。

用類方法來(lái)處理URL路由過(guò)來(lái)的事件,事件傳遞過(guò)來(lái)首先觸發(fā)的是dispatch方法渐北,可以在此處對(duì) get 和 post 做日志記錄等

from django.views import View
class CBV(View):
    def dispatch(self, request, *args, **kwargs):
        print('dispatch....')
        ret = super(CBV,self).dispatch(request, *args, **kwargs)
        return ret
    def get(self,request):
        return HttpResponse("CBV.get")
    def post(self,request):
        return HttpResponse("CBV.post")

get和post方法在返回過(guò)程中阿逃,可以添加響應(yīng)頭,返回給客戶端

def post(self,request):
    ret = HttpResponse("CBV.post")
    ret['c1'] = 'v2'
    ret.set_cookie('c2', 'v2')
    return ret

在 filter赃蛛, value恃锉, 條件中,外鍵如果要跨表查詢呕臂,必須把 . 改為 __破托,可以跨多張表查詢

# cs 為外鍵
# models.Student.objects.filter(cs.id = nid).delete() 這樣不行,必須改為
models.Student.objects.filter(cs__id = nid).delete() 

django 練習(xí)的一個(gè)在頁(yè)面上對(duì)數(shù)據(jù)庫(kù)的操作歧蒋,文件太多土砂,不好全發(fā)上來(lái),只記錄一些重要的谜洽,

# models.py 表格文件
from django.db import models

# Create your models here.

class Classes(models.Model):
    title = models.CharField(max_length=32)
    m = models.ManyToManyField("Teacher")

class Teacher(models.Model):
    name = models.CharField(max_length=32)

class Student(models.Model):
    username = models.CharField(max_length=32)
    age = models.IntegerField()
    gender = models.NullBooleanField()
    cs = models.ForeignKey("Classes",on_delete=models.CASCADE)

下面是 classes 表的操作

# views 文件下的 Classes.py
from django.shortcuts import render,HttpResponse,redirect
from app01 import models

def get_classes(request): # 獲取表格數(shù)據(jù)
    class_list = models.Classes.objects.all()
    for c in class_list:
        print(c.m.all())
    return render(request, "classes.html", {"class":class_list})

def add_classes(request): # 添加數(shù)據(jù)
    if request.method == "POST":
        title = request.POST.get("title")
        print("title: ",title)
        if title:
            models.Classes.objects.create(title=title, )
            back = "添加成功萝映,你添加的字段為:" + '"'+ title + '"'
        else:
            back = "添加失敗,你提交的是空字段阐虚。"
        return render(request, "add_classes.html",{"back":back})
    else:
        return render(request, "add_classes.html")

def del_classes(request): # 刪除數(shù)據(jù)
    if request.method == "GET":
        nid = request.GET.get("nid")
        # print("---------------------------",nid)
        # title = models.Classes.objects.filter(id=nid).values("title")[0]["title"]
        # print("title: ", title)
        models.Classes.objects.filter(id=nid).delete()
        # back = "刪除 " + nid + "," + title + " 成功序臂。"
        # return HttpResponse(back)
    return redirect("/classes.html")

def edit_classes(request): # 編輯數(shù)據(jù)
    if request.method == "GET":
        nid = request.GET.get('nid')
        data_list = models.Classes.objects.filter(id=nid)[0]
        return render(request, "edit_classes.html", {"back":data_list})
    elif request.method == "POST":
        title = request.POST.get("title")
        nid = request.POST.get("nid")
        print("title: ", title)
        print("nid: ", nid)
        models.Classes.objects.filter(id=nid).update(title=title)
        return redirect("/classes.html")
    else:
        return redirect("/classes.html")

def set_teachers(request): # 設(shè)置
    if request.method == "GET":
        nid = request.GET.get("nid")
        teachers_list = models.Teacher.objects.all().values("id","name")
        select_teachers = models.Classes.objects.filter(id=nid).values_list("m","m__name")
        print(select_teachers)
        select_teachers_id = list(zip(*select_teachers))[0]
        print(select_teachers_id)
        return render(request,"set_teachers.html",
                      {
                          "teachers_list":teachers_list,
                          "select_teachers_id":select_teachers_id,
                          "nid":nid
                      })
    elif request.method == "POST":
        teachers_list = request.POST.getlist("teachers_list")
        nid = request.POST.get("nid")
        print("------------------",teachers_list)
        print(nid)
        ret = models.Classes.objects.filter(id=nid)[0]
        ret.m.set(teachers_list)
        return redirect("/classes.html")
    else:
        return redirect("/classes.html")

def set_class(request): # 相對(duì)應(yīng)的students 表的 ajax 刪除
    if request.method == "GET":
        nid = request.GET.get("nid")
        classes_list = models.Classes.objects.all()
        cs = models.Student.objects.filter(id=nid).values("id","cs_id")
        print(classes_list)
        print(cs)
        return  render(request,"set_teachers.html",{
            "nid":nid,
            "classes_list":classes_list,
            "cs":cs
        })

與其相對(duì)應(yīng)的 classes.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .table{
            margin-top: 50px;
            margin-left: 50px;
            color: red;
        }
        a{
            text-decoration: none;
        }
        .add{
            margin-left: 50px;
            margin-top: 50px;
            margin-bottom: -20px;
        }
        .classes{
            float: left;
        }

    </style>
</head>
<body>
    <div class="add">
        <a href="/add_classes.html">添加</a>
    </div>
    <div class="classes">
        <table border="1px" cellpadding="15px" cellspacing="4px" class="table">
            <thead>
                <tr>
                    <th>id</th>
                    <th>班級(jí)名稱</th>
                    <th>老師</th>
                    <th colspan="4">操作</th>
                </tr>
            </thead>
            <tbody>
               {% for foo in class %}
                    <tr>
                        <th>{{ foo.id }}</th>
                        <th>{{ foo.title }}</th>
                        <th>
                            {% for i in foo.m.all.values %}
                                <span>{{ i.name }}</span>
                            {% endfor %}
                        </th>
                        <th><a href="/del_classes.html/?nid={{ foo.id }}">刪除</a></th>
                        <th><a href="/edit_classes.html/?nid={{ foo.id }}">修改</a></th>
                        <th><a href="/set_teachers.html/?nid={{ foo.id }}">分配老師</a></th>
                        <th><a href="/set_class.html/?nid={{ foo.id }}">分配班級(jí)</a></th>
                    </tr>
               {% endfor %}
            </tbody>
        </table>
    </div>
</body>
</html>

效果圖


students.py 學(xué)生表操作

# views 下的 students.py 文件
from django.shortcuts import render,redirect,HttpResponse
from app01 import models

def get_students(request):
    data_list = models.Student.objects.all()
    return render(request, "students.html",{'students':data_list})

def add_student(request):
    if request.method == "GET":
        cs_list = models.Classes.objects.all().values("title","id")
        return render(request, "add_students.html", {"cs_list":cs_list})
    elif request.method == "POST":
        username = request.POST.get("username")
        age = request.POST.get('age')
        gender = request.POST.get('gender')
        cs= request.POST.get('cs')
        models.Student.objects.create(username=username,age=age,gender=gender,cs_id=cs)
        return redirect("/students.html")
    else:
        return redirect("/students.html")

def del_students(request):
    if request.method == "GET":
        nid = request.GET.get('nid')
        models.Student.objects.filter(id=nid).delete()
    return redirect("/students.html")

def edit_students(request):
    if request.method == "GET":
        nid = request.GET.get("nid")
        data_dic = models.Student.objects.filter(id=nid)[0]
        class_dic = models.Classes.objects.all().values("title","id")
        print(class_dic)
        return render(request, "edit_students.html",{"data_dic":data_dic,"class_dic":class_dic})
    elif request.method == "POST":
        nid = request.POST.get("nid")
        username = request.POST.get("useranme")
        gender = request.POST.get("gender")
        age = request.POST.get("age")
        cs = request.POST.get("cs")
        models.Student.objects.filter(id=nid).update(
            username=username,
            gender=gender,
            age=age,
            cs_id=cs
        )
        return  redirect("/students.html")
    else:
        return redirect("/students.html")

students.html 文件,包含了 ajax

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .table{
            margin-top: 50px;
            margin-left: 50px;
            color: red;
        }
        a{
            text-decoration: none;
        }
        .add{
            margin-left: 50px;
            margin-top: 50px;
            margin-bottom: -20px;
        }
        .classes{
            float: left;
        }

    </style>
</head>
<body>
    <div class="add">
        <a href="/add_students.html">添加</a>
    </div>
    <div class="classes">
        <table border="1px" cellpadding="15px" cellspacing="4px" class="table">
            <thead>
                <tr>
                    <th>id</th>
                    <th>姓名</th>
                    <th>年齡</th>
                    <th>性別</th>
                    <th>班級(jí)</th>
                    <th colspan="3">操作</th>
                </tr>
            </thead>
            <tbody>
               {% for foo in students %}
                    <tr nid="{{ foo.id }}">
                        <th>{{ foo.id }}</th>
                        <th>{{ foo.username }}</th>
                        <th>{{ foo.age }}</th>
                        {% if foo.gender %}
                            <th>男</th>
                        {% else %}
                            <th>女</th>
                        {% endif %}
                        <th>{{ foo.cs.title }}</th>
                        <th><a href="/del_students.html/?nid={{ foo.id }}">刪除</a></th>
                        <th><a onclick="ajax_del(this)">Ajax刪除</a></th>
                        <th><a href="/edit_students.html/?nid={{ foo.id }}">修改</a></th>
                    </tr>
               {% endfor %}
            </tbody>
        </table>
    </div>
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        function ajax_del(that) {
            var nid = $(that).parent().parent().attr("nid");
            $.ajax({
                url: "/ajax_del.html",
                type: "get",
                data : {"nid":nid},
                success:function (arg) {
                    if (arg == "successful"){
                        console.log(arg);
                        $(that).parent().parent().remove()
                    }else{
                        alert(arg);
                    }
                }
            })
        }
    </script>
</body>
</html>

setting 設(shè)置靜態(tài)文件路徑实束、MySQL數(shù)據(jù)庫(kù)奥秆,static目錄逊彭、打印數(shù)據(jù)庫(kù)操作日志
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'books',    #你的數(shù)據(jù)庫(kù)名稱
        'USER': 'root',   #你的數(shù)據(jù)庫(kù)用戶名
        'PASSWORD': '89828', #你的數(shù)據(jù)庫(kù)密碼
        'HOST': '', #你的數(shù)據(jù)庫(kù)主機(jī),留空默認(rèn)為localhost
        'PORT': '3306', #你的數(shù)據(jù)庫(kù)端口
    }
}

STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
    - 所有學(xué)生的姓名以及其所在班級(jí)名稱,QuerySet,也就是列表類型
        stu_list = Student.objects.all()
        select * from tb;
        [obj,obj,obj,obj] 拿到的是對(duì)象吭练,對(duì)象 obj.name 就可以訪問(wèn)屬性
        
        stu_list = Student.objects.all().values("id",'username')
        select id,username from tb;
        [{"id":1,'username':'xx'},{id:'',username:''}] value 拿到的是列表內(nèi)封裝的字典   
        
        stu_list = Student.objects.all().values_list("id",'username')
        [(1,'root'), (2,'alex')] value_list 拿到的是列表內(nèi)封裝的元組
         
        
        stu_list = Student.objects.all().values('username',"cs__name") cs__name 跨表查詢
        for row in stu_list:
            print(row['username'],row['cs__name']) 遍歷 stu_list ,記住诫龙,row為字典
        
        stu_list = Student.objects.all().values('username',"cs__titile",“cs__fk__name”)
        
    - 找到3班的所有學(xué)生
        Student.objects.filter(cs__name='3班')
        
        obj = Classes.objects.filter(name='3班').first()

    
1. 類代表數(shù)據(jù)庫(kù)表
2. 類的對(duì)象代指數(shù)據(jù)庫(kù)的一行記錄
3. FK字段代指關(guān)聯(lián)表中的一行數(shù)據(jù)(類的對(duì)象)
4. 
    - 正向:fk字段  (*****能用正向就用正向) 
    - 反向:小寫類名_set(默認(rèn))   ==> related_name='ssss'
    假設(shè)存在兩張表class和student,student的外鍵fk關(guān)聯(lián)class表鲫咽,cs = models.ForeignKey(Classes) 
    那么從cs就可以直接指向class表的某個(gè)數(shù)據(jù)签赃,反過(guò)來(lái),從class表也可以指向student表分尸,
    所得出的list為student下同一個(gè)指定老師的集合锦聊,通過(guò)obj.student_set.all() ,obj 為所選擇的某個(gè)class對(duì)象
    
    也可以更改默認(rèn)反向默認(rèn)查找字段,在 cs = models.ForeignKey(Class,related_name="ssss")
5. 誰(shuí)是主表箩绍?就全部列出其數(shù)據(jù)
    models.Student.objects.all().values('username', 'cs__titile') 列出所有學(xué)生的數(shù)據(jù)孔庭,包括班級(jí)
    models.Classes.objects.all().values('titile', 'ssss__username') 列出所有班級(jí)的數(shù)據(jù),
    values 列出來(lái)的數(shù)據(jù)不為對(duì)象材蛛,為值
    
4. M2M字段圆到,自動(dòng)生成第三張表;依賴關(guān)聯(lián)表對(duì)第三張表間接操作
    Classes 添加 m = manytomany字段卑吭,關(guān)聯(lián)Student
    obj.m.all() 列出關(guān)聯(lián)學(xué)生的所有老師
    obj.m.add(3) 添加
    obj.m.set([1,2]) 設(shè)置芽淡,不為1,2的刪除
    在student表中的對(duì)象也可以關(guān)聯(lián)
    obj.classes_set.all() 等

對(duì)話框添加,刪除豆赏,修改:
    添加:
        Ajax偷偷向后臺(tái)發(fā)請(qǐng)求:
            1. 下載引入jQuery
            2. 
                $.ajax({
                    url: '/add_classes.html',
                    type: 'POST',
                    data: {'username':'root','password': '123'},
                    success:function(arg){
                        // 回調(diào)函數(shù)挣菲,arg是服務(wù)端返回的數(shù)據(jù)
            // window.location.reload(); JS 主動(dòng)刷新頁(yè)面
                    }
                })
      
ajax補(bǔ)充:data: $("#fm").serialize()

django

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市掷邦,隨后出現(xiàn)的幾起案子白胀,更是在濱河造成了極大的恐慌,老刑警劉巖抚岗,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件或杠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡宣蔚,警方通過(guò)查閱死者的電腦和手機(jī)廷痘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)件已,“玉大人,你說(shuō)我怎么就攤上這事元暴∨窭” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵茉盏,是天一觀的道長(zhǎng)鉴未。 經(jīng)常有香客問(wèn)我枢冤,道長(zhǎng),這世上最難降的妖魔是什么铜秆? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任淹真,我火速辦了婚禮,結(jié)果婚禮上连茧,老公的妹妹穿的比我還像新娘核蘸。我一直安慰自己,他們只是感情好啸驯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布客扎。 她就那樣靜靜地躺著,像睡著了一般罚斗。 火紅的嫁衣襯著肌膚如雪徙鱼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天针姿,我揣著相機(jī)與錄音袱吆,去河邊找鬼。 笑死距淫,一個(gè)胖子當(dāng)著我的面吹牛绞绒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播溉愁,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼处铛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拐揭?” 一聲冷哼從身側(cè)響起撤蟆,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堂污,沒(méi)想到半個(gè)月后家肯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盟猖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年讨衣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片式镐。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡反镇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娘汞,到底是詐尸還是另有隱情歹茶,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站惊豺,受9級(jí)特大地震影響燎孟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尸昧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一揩页、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烹俗,春花似錦爆侣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至磁浇,卻和暖如春斋陪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背置吓。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工无虚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人衍锚。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓友题,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親戴质。 傳聞我的和親對(duì)象是個(gè)殘疾皇子度宦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容