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
安裝:html
pip install django==1.8.2
建立項目:前端
django-admin startproject test1
目錄說明:python
manage.py
:一個命令行工具,可使你用多種方式對Django項目進行交互-_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語句,去數據庫執行
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模塊
ORM
類似的數據,一類的數據放在同一張表中。具備相同屬性,放在同一張表中。
ORM DB 類 數據表 屬性 字段 對象 數據行
優勢:開發效率高;不用直接寫SQL語句;後端數據庫變更,ORM適配。
缺點:執行效率低;SQL語句可能不是最優。
建立視圖與ORM的app
不一樣的功能放在不一樣的包中
> python manage.py startapp appname
views
的視圖settings.py
中從新配置,在字段INSTALL_APPS
增長: app.apps.AppConfig
Django使用mysql
create database djsite
配置Django鏈接數據庫,可使用多個數據庫(讀寫分離,主從服務器)
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'djsite', 'HOST': '127.0.0.1', 'PROT': 3306, 'USER': 'root', 'PASSWORD': '' } }
使用第三方的包鏈接數據庫:pymysql
, MySQLDb
(支持py2),在djsite
項目的__init__.py
中告知Django
使用pymysql
import pymysql pymysql.install_as_MySQLdb()
建立一張表,在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)
models.py
中變動的記錄下來:python manage.py makemigrations
python manage.py migrate
視圖中使用
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.py
中CURD
操做:
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)
變量相關:{{}}
邏輯相關:{% %}
點.
在模版語言中,有特殊的含義,順序爲:
{{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
app
中新建一個templatetags
包(名字固定,不能變,只能是這個),和views.py
、models.py
等文件處於同一級別目錄下。這是一個包!不要忘記建立__init__.py
文件以使得該目錄能夠做爲Python的包。在建立的包中,建立.py
文件做爲過濾器文件
from django import template # 生成註冊實例 register = template.Library() @register.filter # 告知模版語言,自定義的filter def counter(val): ''' counter :params {val} 管道符參數 :return {} ''' return val + 'counter'
在.html
視圖文件中導入,並使用。
# 導入filter模塊 {% load counter %} # 使用該過濾器 {{ret|counter}}
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
mytags
編輯文件
from django import template register = template.Library()
定義函數,能夠接收參數,須要返回字典
@register.include_tag(filename) # 組件名字 def pagination(total): return {'total': total}
使用
{% load mytags %} { pagination 10 }
一個視圖函數(類)稱之爲視圖,它接受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())
流程:
views.AddPress.as_view()
獲取源碼的view
函數當請求到來的時候執行view
函數
實例化本身定義的類賦值給self
self = cls(**initkwargs)
self.request = request
執行父類中的self.dispatch(request, *args, **kwargs)
self.dispatch(request, *args, **kwargs)
判斷請求方式是否被容許
handler = 容許的請求下經過**反射**獲取本身定義的類中的`get`, `post`方法
不容許的狀況下
handler = 不容許的狀況, 父類中的http_method_not_allowed方法
執行handler
方法
返回HttpResponse
對象
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 反向解析
字段類型
類型 | 說明 |
---|---|
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=False 和blank=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個方法
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') # 表名__字段名