Python_Django

MVC
  • 大部分開發語言中都有MVC框架
  • MVC框架的核心思想是:解耦
  • 下降各功能模塊之間的耦合性,方便變動,更容易重構代碼,最大程度上實現代碼的重用
  • m表示model,主要用於對數據庫層的封裝
  • v表示view,用於向用戶展現結果
  • c表示controller,是核心,用於處理請求、獲取數據、返回結果
MVT
  • Django是一款python的web開發框架
  • MVC有所不一樣,屬於MVT框架
  • m表示model,負責與數據庫交互
  • v表示view,是核心,負責接收請求、獲取數據、返回結果
  • t表示template,負責呈現內容到瀏覽器

客戶端 -> 視圖View -> 模型Model -> Mysql -> 模型Model -> 視圖View -> 模版Template -> 視圖View -> 客戶端css

clipboard.png

clipboard.png

Django環境

安裝:html

pip install django==1.8.2

建立項目:前端

django-admin startproject test1

目錄說明:python

clipboard.png

  • manage.py:一個命令行工具,可使你用多種方式對Django項目進行交互-
  • 內層的目錄:項目的真正的Python包
  • _init _.py:一個空文件,它告訴Python這個目錄應該被看作一個Python包
  • settings.py:項目的配置
  • urls.py:項目的URL聲明
  • wsgi.py:項目與WSGI兼容的Web服務器入口

啓動項目:mysql

python manage.py runserver 8181
擴展項目目錄
|-- app/                     # 應用主目錄
    |-- templates/           # html 模板目錄
        |-- app/
            |-- home.html    # 主頁html
            |-- login.html   # 登錄頁html
            |-- about.html   # 關於頁html
            |-- ...
    |-- static/              # 靜態資源目錄
        |-- js/              # js資源目錄
            |-- lib/         # js library 資源目錄
            |-- page1/       # 頁面1 js資源目錄
            |-- page2/       # 頁面2 js資源目錄
            |-- ...
        |-- css/             # css資源目錄
        |-- images/          # 圖片資源目錄
        |-- ...



    |-- admin.py             # 配置模型models在django原生後臺的管理
    |-- apps.py              # 應用級別的配置
    |-- forms.py             # 表單處理邏輯
    |-- managers.py          # 模型處理邏輯
    |-- models.py            # 模型定義
    |-- urls.py              # 路由設置
    |-- views.py             # 控制層
    |-- tests.py
先後端項目分離

後端:web

|-- app/                     # 應用主目錄
    |-- admin.py             # 配置模型models在django原生後臺的管理
    |-- apps.py              # 應用級別的配置
    |-- forms.py             # 表單處理邏輯
    |-- managers.py          # 模型處理邏輯
    |-- models.py            # 模型定義
    |-- urls.py              # 路由設置
    |-- views.py             # 控制層
    |-- tests.py

前端:ajax

|-- src/
    |-- app/
        |-- home/            # 主頁工做目錄
            |-- index.html   # html 入口文件
            |-- index.js     # js 入口文件
            |-- ...
        |-- login/           # 登錄頁工做目錄
        |-- about/           # 關於頁工做目錄
        |-- ...
Django有關命令

django安裝:正則表達式

pip install django==1.11.11
pip install -i yuan django=1.11.11

建立目錄:sql

django-admin startproject filename

建立App:數據庫

python manage.py startapp appname

啓動項目:

python manage.py runserver # 127.0.0.1:8000
python manage.py runserver 80 # 127.0.0.1:80
python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80

數據庫相關:

python manage.py makemigrations # 記錄modules的變化,將變動的記錄更新到 對應App下到migrations
python manage.py migrate # 翻譯成SQL語句,去數據庫執行

Django基礎使用

app的概念:一個大項目中劃分紅不少功能模塊

配置靜態目錄
# 在setting.py中, Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/' # alise

STATIC_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
django基礎三件套
from django.shortcuts import HttpResponse, render

HttpResponse
render
redirect // 返回一條命令,瀏覽器再去請求重定向的地址
使用PY連接MySql

使用pymysql模塊

  1. 導入pymysql模塊
  2. 建立鏈接
  3. 獲取執行命令的遊標
  4. 用遊標去執行SQL語句
  5. 獲取SQL語句的執行結果
  6. 關閉遊標
  7. 關閉鏈接
ORM

類似的數據,一類的數據放在同一張表中。具備相同屬性,放在同一張表中。

ORM      DB
類       數據表
屬性     字段
對象     數據行

優勢:開發效率高;不用直接寫SQL語句;後端數據庫變更,ORM適配。
缺點:執行效率低;SQL語句可能不是最優。

建立視圖與ORM的app

不一樣的功能放在不一樣的包中

> python manage.py startapp appname
  • 從新在使用的地方引入新的views的視圖
  • settings.py中從新配置,在字段INSTALL_APPS增長: app.apps.AppConfig
Django使用mysql
  1. 手動建立一個數據庫create database djsite
  2. 配置Django鏈接數據庫,可使用多個數據庫(讀寫分離,主從服務器)

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'djsite',
            'HOST': '127.0.0.1',
            'PROT': 3306,
            'USER': 'root',
            'PASSWORD': ''
        }
    }
  3. 使用第三方的包鏈接數據庫:pymysql, MySQLDb(支持py2),在djsite項目的__init__.py中告知Django使用pymysql

    import pymysql
    
    pymysql.install_as_MySQLdb()
  4. 建立一張表,在app/models.py的文件中建立類

    from django.db import models
    
    # Create your models here.
    
    class User(models.Model):
        id = models.AutoField(primary_key=True) # id 主鍵
        email = models.CharField(max_length=32) # varchar(32)
        pwd = models.CharField(max_length=32) # varchar(32)
  5. 使用ORM
    models.py中變動的記錄下來:python manage.py makemigrations
    變動的記錄建立成數據庫語句執行:python manage.py migrate
  6. 視圖中使用

    User.objects.filter(emial=, pwd=) # 查詢數據庫中的字段
模版語言

展現:

{{name}}

for循環:

{%for item in press_list%}
    <tr>
        <td>{{forloop.counter}}</td>
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td><a href="/del_press/?id={{item.id}}">刪除</a></td>
    </tr>
{%endfor%}
配置settings.py

數據庫相關配置:

ENGIGE # 引擎相關  mysql sqllite3
NAME # 數據庫名字
HOST # IP
PORT # 端口 3306
USER # 用戶名
PASSWORD # 密碼, ''

靜態文件相關:

STATIC_URL = 'static' # 別名
STATICFILE_DIRS = [ # 靜態文件地址
    os.path.join(BASE_DIR, 'static')
]

APP:

INSTALL_APP = [
    'app01.apps.App01Config' # 告知django新建了一個名叫app01的應用
    # appName.appFile.appClass
]
ORM關係
class -> 數據表
object -> 行
attr -> 字段

圖書管理系統

表的設計

出版社
    id, name
做者
    id, name
書
    id, title, 出版社_id(一對多,一本書只能選擇一個出版社),
做者和書(多對多的關係,多一張關係表)
    id, 書_id, 做者_id
CURD

模型:

class Press(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)

views.pyCURD操做:

def press_list(request):
    press_list = Press.objects.all().order_by('id')

    return render(request, 'press_list.html', {'press_list': press_list})

def add_list(request):
    if request.method == 'POST':
        press_name = request.POST.get('name')
        Press.objects.create(name=press_name)
        return redirect('/press_list/')

    return render(request, 'add_list.html')

def del_list(request):
    del_id = request.GET.get('id')
    Press.objects.filter(id=del_id).delete()

    return redirect('/press_list/')

def edit_press(request):
    edit_id = request.POST.get('id')
    edit_press = Press.objects.get(id=edit_id)
    if request.method == 'POST':
        new_name = request.POST.get('name')
        edit_press.name = new_name
        edit_press.save() # 注意保存
        return redirect('/press_list/')
        
    return render(request, 'edit_list.html', {'edit_item', edit_press})

ORM語句:

className.objects.all()
className.filter()
className.objects.get()
className.objects.create(name='')
className.objects.filter(id=id).delete()

# 更改
obj = className.objects.get(id=id)
obj.name = newName
obj.save() # 注意保存

# 書籍表結構:
#    id, title, 關係字段(外鍵)

create table_book(
    id int primary_key auto_increment,
    title varchar(30) not null
    press_id int not null,
    constraint fk_press foreign key(press_id) references press(id) on delete cascade update cascade
)

ORM使用外鍵:

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=30)
    press = models.ForeignKey(to='Press', on_delete=models.CASCADE) # 外鍵, 關聯Press表

外鍵查詢:

book_obj.press # 書籍關聯的出版社對象
book_obj.press_id # 數據庫中實際存在的字段值

外鍵修改:

book_obj = Book.objects.create(title='', press=)
book_obj = Book.objects.create(title='', press_id=)

ORM已經存在的表,再次更改字段,沒有默認值,有必須填寫,Django會提示手動輸入默認值。

null=True
default=默認值

price = Press.IntegerField(null=True)
price = Press.IntegerField(default=100)

# 做者表,多對多結構:
# SQL語句:
create table author(id int primary_key auto_increment; name varchar(32) not null);
create table authorToBook(
    id int primary_key auto_increment,
    author_id int not null,
    book_id int not null,
    constraint fk_author foreign key(author_id) references author(id) on delete on update cascade,
    constraint fk_book foreign key(book_id) references book(id) on delete on update cascade
);
對多對的關係查詢的使用

模型:

# ORM建立二張表:
class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)

class AuthorToBook(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(to='Author', on_delete=models.CASCADE)
    book = models.ForeignKey(to='Book', on_delete=models.CASCADE)

# Django中包含多對多的關係字段`ManyToManyField`:
class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    books = models.ManyToManyField(to='Book') # Django包含多對多字段

視圖:

def author_list(request):
    author_data = Author.objects.all()

    # for item in author_data:
    #     print(item.books.all()) # 連表查詢,使用all()查詢出數據來
    return render(request, 'author_list.html', {'author_data': author_data})

界面:

<table>
        <tr>
            <th>序號</th>
            <th>做者id</th>
            <th>做者名字</th>
            <th>做者做品</th>
        </tr>
        {% for author in author_data %}
        <tr>
            <td>{{forloop.counter}}</td>
            <td>{{author.id}}</td>
            <td>{{author.name}}</td>
            <td>
            {% for book in data.books.all %}
                {% if forloop.last %}
                    《{{book.title}}》
                {% else %}
                    《{{book.title}}》,
                {% endif %}
            {% empty %}
                暫無做品
            {% enfor %}
            </td>
        </tr>
        {% endfor %}
    </table>

查詢多對多的關係字段:

author_obj.books.all()

修改:

author_obj.set(['book1', 'book2'])
author_obj.add('book1', 'book2', 'book3')

清除:

author_obj.clear() # 清除對應關係
ORM操做

查:

from app01.models import User, Press, Book, Author

Press.object.all() # 查詢全部出版社對象(對象列表queryset)
Press.object.filter(條件) # 查詢全部知足條件的對象
Press.object.get(條件) # 查詢有且只有一個對象

# 屬性
press_obj.id
press_obj.name

# 外鍵屬性
book_obj.id
book_obj.press # 關聯對象
book_obj.press.id

# 多對多屬性
author_obj.books # 管理對象
author_obj.books.all() # 做者關聯的全部書籍對象

增:

from app01.models import User, Press, Book, Author

new_press_obj = Press.object.create(name='')

# 外鍵的增長
Book.object.create(title='', prece='', press_id=press_obj.id)
Book.object.create(title='', prece='', press=press_obj)

# 多對多關係的增長
new_author_obj = Author.object.create(name='')
new_author_obj.books.set([press_id, press_id])
new_author_obj.books.set([book1, book2])
new_author_obj.books.add(book1, book2)

刪:

book_obj.delete(條件) # 刪除知足條件單個對象
Press.object.filter(條件).delete() # 刪除知足條件的多個對象

改:

press_obj.name = ''
press_obj.save() # 注意修改保存

Press.object.filter(條件).update() # 修改知足條件的多個對象

# 外鍵的修改
book_obj.press = press_obj
book_obj.save()
book_obj.press_id = press_obj.id

# 多對多字段的修改
author_obj.name = ''
author_obj.save()

author_obj.books.set([press_id, press_id])
文件上傳
f_dict = request.FILES.get('name') # 文件字典
    print(f_dict)
    with open(f_dict, 'wb') as f:
        for chunk in f_dict.chunk():
            f.write(chunk)

模版語言

變量相關:{{}}
邏輯相關:{% %}

.在模版語言中,有特殊的含義,順序爲:

  1. 字典查詢
  2. 屬性或方法查詢
  3. 數字索引查詢
{{name}}
{{dict1.name}}
{{list1.0}}

模版語言中方法不用加()執行,Django自動調用,只能調用不帶參數的方法。

filter
# {{變量名|方法|參數}}
{{name|fun}}
{{ value|add:"2" }} # 支持鏈式操做
{{ value|date:"D d M Y" }} {{ value|time:"H:i" }}
  • 過濾器後加個冒號,再緊跟參數,中間不能有空格。
  • 支持一個參數。

if語句支持過濾器, and, or, ==, <, >, in, !=, is, is not, not in, <=, >=

自定義filter
  1. app中新建一個templatetags包(名字固定,不能變,只能是這個),和views.pymodels.py等文件處於同一級別目錄下。這是一個包!不要忘記建立__init__.py文件以使得該目錄能夠做爲Python的包
  2. 在建立的包中,建立.py文件做爲過濾器文件

    from django import template
    
    # 生成註冊實例
    register = template.Library()
    
    @register.filter # 告知模版語言,自定義的filter
    def counter(val):
        '''
            counter
            :params {val} 管道符參數
            :return {}
        '''
        return val + 'counter'
  3. .html視圖文件中導入,並使用。

    # 導入filter模塊
    {%  load counter  %}
    # 使用該過濾器
    {{ret|counter}}
  4. 須要重啓django項目。
csrf

CSRF通常是POST請求:

{% csrf_token %}
  • <form>...</form>標籤;
  • 使用POST的方法時,必須添加{% csrf_token %}標籤,用於處理csrf安全機制
  • {{ form }}表明Django爲你生成其它全部的form標籤元素,提交按鈕須要手動添加;
母板與繼承
# 子頁面中繼承父頁面
{% extends 'list/base.html' %}

# 父級頁面`base.html`
{% block contenter %}
{% endblock %}

# 子頁面
{% block contenter %}
{% endblock %}
組件
# 引入組件
{% include 'nav.html' %}
靜態文件
{% load static %}

<link href="{% static % 'bootstrap-3.3.7/css/bootstrap.css'}" />

{% load static %}
{% get_static_prefix %} # 去settings.py中獲取STATIC_URL的value值
自定義inclusion_tags
  1. 在app下建立一個templatetags的python包
  2. 在包下寫py文件,mytags
  3. 編輯文件

    from django import template
    register = template.Library()
  4. 定義函數,能夠接收參數,須要返回字典

    @register.include_tag(filename) # 組件名字
    def pagination(total):
        return {'total': total}
  5. 在模版文件中使用字典參數,進行渲染
  6. 使用

    {% load mytags %}
    { pagination 10 }

Django中的視圖

一個視圖函數(類)稱之爲視圖,它接受Web請求而且返回Web響應。
響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片。
不管視圖自己包含什麼邏輯,都要返回響應。爲了將代碼規範,約定俗成將視圖放置在項目(project)或應用程序(app)目錄中命名爲view.py文件中。

FBV(Function Based View)
def login(request):
    # return HttpResponse('ok')
    # print(request.POST, 'post')
    # print(request.Method, 'method')
    # print(request.GET, 'get')
    return render(request, 'login.html', {'ret': 'test'})
CBV(class Based View)
from django.views import View

class AddPress(View):
    def get(self, request):
        return render(request, 'add_press.html')

    def post(self, request):
        press_name = request.POST.get('name')
        Press.objects.create(name=press_name)
        return rediract('/press_list/')

url.py中使用

url(r'/add_press/', views.AddPress.as_view())

流程:

  1. views.AddPress.as_view()獲取源碼的view函數
  2. 當請求到來的時候執行view函數
    實例化本身定義的類賦值給self

    self = cls(**initkwargs)

    self.request = request
    執行父類中的self.dispatch(request, *args, **kwargs)

  3. self.dispatch(request, *args, **kwargs)
    判斷請求方式是否被容許

    handler = 容許的請求下經過**反射**獲取本身定義的類中的`get`, `post`方法

    不容許的狀況下

    handler = 不容許的狀況, 父類中的http_method_not_allowed方法

    執行handler方法
    返回HttpResponse對象

  4. 把返回HttpResponse對象返回給Django
requset和response對對象:

requset對象:

['COOKIES', 'FILES', 'GET', 'META', 'POST', 'body', 'build_absolute_uri', 'close', 'content_params', 'content_type', 'csrf_processing_done', 'encoding', 'environ', 'get_full_path', 'get_host', 'get_port', 'get_raw_uri', 'get_signed_cookie', 'is_ajax', 'is_secure', 'method', 'parse_file_upload', 'path', 'path_info', 'read', 'readline', 'readlines', 'resolver_match', 'scheme', 'session', 'upload_handlers', 'user', 'xreadlines']

requset經常使用的對象:

requset.method
requset.GET
requset.POST
requset.FILES
requset.COOKIES
requset.path_info
requset.body
requset.scheme # 協議
requset.encoding # 編碼
requset.META # 元數據

requset.get_host() # ip:host
requset.is_ajax() # 是不是ajax請求

response對象:

from django.shortcuts import redner, HttpResponse, redirect

HttpResponse('字符串')
redner(requset, 'xxx.html', {ret: ret})
redirect('跳轉地址') # Location

# 返回json數據,序列化
from django.http import JsonResponse
def json_data(request):
    ret = {'name': 'su', 'age': 30}
    # return HttpResponse(json.dumps(ret)) # Content-Type: text/html charset=utf-8
    return HttpResponse(json.dumps(ret), content_type: 'application/json')
    return JsonResponse(ret) # Content-Type: application/json

路由

URL是Web服務的入口,用戶經過瀏覽器發送過來的任何請求,都是發送到一個制定的URL地址,而後被響應。

urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表達式,一旦匹配成功則再也不繼續。

分組
url(r'^test/(\d{4})/\d{2}$', views.test) # test函數接收到正則匹配分組的參數

命名分組:

url(r'^test/(?P<year>\d{4})/\d{2}$', views.test) # test函數接收到正則匹配分組的year參數,也能夠經過`args`或`**kwargs`來獲取參數
視圖默認參數
# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"): # 當沒有傳遞使用num=1
    pass
路由轉發

一般,在每一個app裏,各自建立一個urls.py路由模塊, 而後從根路由出發,將app所屬的url請求,所有轉發相應的urls.py模塊中。

項目目錄的url.py下:

from django.conf.urls import include, url

urlpatterns = [
    url(r'^community/', include('app.aggregator.urls')),
    url(r'^contact/', include('app.contact.urls')),
]

app/aggregator/urls.py下:

from django.conf.urls import url
from app import views

urlpatterns = [
    url(r'^test/', views.test)
]

地址欄訪問方式:127.0.0.1:8000/app/test, test是app下定義的路由

命名URL和URL反向解析

命名:

url(r'press_list/', views.press_list, name='press_list') # 命名
url(r'^home/(\d{4})/(\d{2})/$', views.home, name=home) # 分組
url(r'^home/(?P<year>\d{4})/(?P<month>\d{2})/$', views.home, name=home) # 命名分組

反向:

# 視圖中應用
from django.shortcuts import redirect, reverse

def press_list():
    # reverse('press_list') -> /press_list/
    redirect(reverse('press_list'))

    # url(r'^home/(\d{4})/(\d{2})/$')
    redirect(reverse('home', args=('2018', '12'))) # 分組,須要傳遞參數 'app/home/2018/12'

    # url(r'^home/(?P<year>\d{4})/(?P<month>\d{2})/$', views.home, name=home)
    redirect(reverse('home', kwargs={'year': 2018, 'month': 12})) # 命名分組

# 模版中應用
{% url 'press_list' %}  # 命名
{% url 'home' '2018' '11' %}  # 分組
{% url 'home' year='2018' month='10' %}  # 命名分組
命名空間 namespace
# urls
url(r'^app01/', include('app01.urls', namespace='app01'))
url(r'^app02/', include('app02.urls', namespace='app02'))

# 視圖中使用
def home(request):
    reverse('app01:home')
    return HttpResponse('ok')
def delete(request, table, del_id):
    table_class = getattr(models, table.capitalize()) # getattr() 字符串映射到對象
    table_class.objects.get(id=del_id).delete()

    return redirect(reverse(table)) # reverse 反向解析

ORM

字段類型
類型 說明
AutoField 自增整數類型字段。Django會自動添加字段: `id = models.AutoField(primary_key=True),從1開始計數。主鍵
BooleanField 布爾值類型。默認值是None。在HTML表單中表現爲CheckboxInput標籤,若是要接受null只,使用NullBooleanFiled
CharField 字符串類型。 必須接受字段max_length,表示字符串長度不能超過該值,默認的標籤Input text,最經常使用的filed。
DateField class DateField(auto_now=False, auto_now_add=False, **options)日期類型。一個Python中的datetime.date的實例。在HTML中表現爲TextInput標籤。Django會幫你自動添加一個JS的日曆表和一個「Today」快捷方式,以及附加的日期合法性驗證。兩個重要參數:(參數互斥,不能共存) auto_now: 每當對象被保存時將字段設爲當前日期,經常使用於保存最後修改時間。auto_now_add:每當對象被建立時,設爲當前日期,經常使用於保存建立日期(注意,是不可修改的)。設置上面兩個參數就至關於給field添加了editable=Falseblank=True屬性。若是想具備修改屬性,請用default參數。例:pub_time = models.DateField(auto_now_add=True),自動添加發布時間。
EmailField 郵箱類型,默認max_length最大長度254位。
FileField class FileField(upload_to=None, max_length=100, **options)上傳文件類型
ImageField 圖像類型
FilePathField 文件路徑信息。以字符串的形式存在,默認最大長度100,能夠經過max_length參數設置。
IntegerField 整數類型,最經常使用的字段之一。取值範圍-2147483648到2147483647。在HTML中表現爲NumberInput標籤。
GenericIPAddressField class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)[source]IPV4或者IPV6地址,字符串形式
TextField 大量文本內容,在HTML中表現爲Textarea標籤
URLField 一個用於保存URL地址的字符串類型,默認最大長度200。
UUIDField 用於保存通用惟一識別碼(Universally Unique Identifier)的字段。使用Python的UUID類

UUIDField: 須要設置default參數

import uuid
from django.db import models

def MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # other filed
Meta配置
class UserInfo(models.Model):
    nid = models.AutoField(primary_key=True)
    username = models.CharField(max_length=32)

    # 表進行相關配置
    class Mate:
        db_table = 'table_name' # 數據庫中生成的表名,默認:appname + 下劃線 + 類名
        verbose_name = '我的信息' # admin中顯示的表名稱
        index_together = [ # 聯合索引
            ('pub_date', 'deadline') # 應爲兩個存在的字段
        ]
        unique_together = (('driver', 'restaurant'),) # 聯合惟一索引
查詢數據的13個方法

django ORM操做

import os

if __name__ == '__main__':
    os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘project_name.settings’) # 設定配置文件
    import django
    django.setup()

    from appname import models # 導入app中的模塊

    # all() 全部對象列表
    # p = models.Person.objects.all()

    # get() 獲取多個對象列表
    # p = models.Person.objects.get(id=id) # 查詢不到報錯

    
    # filter() 知足條件的對象列表
    # p = models.Person.objects.filter(id=1)

    # exclude() 不知足條件的對象列表
    # p = models.Person.objects.exclude()

    # values() # 取具體的數據的對象列表。 字典形式key: val
    # 沒有指定參數,是全部的表的字段,能夠制定某些字段。
    # p = models.Person.objects.all().values()
    # p = models.Person.objects.all().values('id', 'name')

    # values_list() # 取具體的數據的對象列表。元祖形式 val
    # 沒有指定參數,是全部的表的字段,能夠制定某些字段。
    # p = models.Person.objects.all().values_list()

    # order_by() # 排序
    # p = models.Person.objects.all().order_by('id')
    # p = models.Person.objects.all().order_by('-id') # 降序
    # p = models.Person.objects.all().order_by('age', 'id') # 多個字段排序

    # reverse() # 反序
    # p = models.Person.objects.all().order_by().reverse() # 須要進行排序後再反轉

    # distinct() # 去重

    # count() # 統計
    # p = models.Person.objects.all().count()

    # first(), last()
    # p = models.Person.objects.all().first()
    # p = models.Person.objects.filter().first()

    # exists() # 是否存在數據
    # p = models.Person.objects.all().exists()
    print(p)
單表查詢
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djsite.settings")
    import django
    django.setup()

    from app01 import models

    ret = models.Person.objects.filter(id__gt=1) # 大於
    ret = models.Person.objects.filter(id__lt=4) # 小於
    ret = models.Person.objects.filter(id__gte=1) # 大於等於
    ret = models.Person.objects.filter(id__lte=1) # 小於等於
    ret = models.Person.objects.filter(id__in=[1, 3]) # 小於等於

    ret = models.Person.objects.filter(id__in=[1, 3]) # id=1, id=3
    ret = models.Person.objects.filter(id__lt=1, id__gt=3) # 1 < x < 3
    ret = models.Person.objects.filter(id__range=[1, 3])

    ret = models.Person.objects.filter(name__contains='e') # name包含e,模糊查詢
    ret = models.Person.objects.filter(name__icontains='e') # name包含e,忽略大小寫,模糊查詢

    ret = models.Person.objects.filter(name__startswith='e') # 開頭包含e
    ret = models.Person.objects.filter(name__istartswith='e') # 開頭包含e,忽略大小寫

    ret = models.Person.objects.filter(name__endswith='e') # 結尾包含e
    ret = models.Person.objects.filter(name__iendswith='e') # 結尾包含e,忽略大小寫

    ret = models.Person.objects.filter(birth_year=2018) # 2018年份
    ret = models.Person.objects.filter(birth_month=12) # 12月份
    ret = models.Person.objects.filter(birth_day=12) # 天數

    print(ret, 'ret')
外鍵查詢

django終端打印SQL語句:

# 配置在`settings.py`中
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

#!/usr/bin/env python
import os
import sys

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djsite.settings')

    import django

    django.setup()

    from app import models

    book_obj = models.Book.objects.get(id=2)

    obj1 = models.Book.objects.filters(publisher__name='xxxx') # INNER JOIN 聯表查詢
    obj2 = models.Book.objects.all().values('title', 'publisher__name') # 表名__字段名

多對多的查詢

相關文章
相關標籤/搜索