1、project 與app之間的關係html
1個project中可包含多個appjava
eg:包含兩個app的project的結構python
project:存放對各個app的配置mysql
app:真正的業務代碼,包含models和views,以package的形式存在,web
容易完整移植到其餘project,從而被多個project複用
redis
2、用python代碼定義表結構sql
一、python經過models實現create table的操做:mongodb
from django.db import models class Book(models.Model): name = models.CharField(max_length=50) pub_date = models.DateField()
二、python代碼定義表結構的好處數據庫
1)無需考慮不一樣數據庫平臺的兼容性問題,不管是mysql,mongodb,redisdjango
從python代碼create table的方式都是同樣的
2)開發者專一於python代碼,不用再去寫sql,減輕大腦負擔
3)django框架中有特定的數據類型, eg:email類型,url類型
4)性能考慮:不用每次系統啓動或者發起請求都要先檢查一下數據庫結構,而是
能夠根據python代碼就知道了目標數據庫的結構。
三、缺點
每次修改了python數據庫結構後,須要手動修改數據庫中的表結構
3、測試models在django中的使用
一、基本準備
1)建立django project和app
2)修改settings.py中的基本設置
模板位置:
TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates'), )
數據庫鏈接:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_db', 'USER': 'root', 'PASSWORD': 'feng', 'HOST': '127.0.0.1', 'PORT': '3306', } }
僅安裝當前使用的app:
INSTALLED_APPS = ( # 'django.contrib.admin', # 'django.contrib.auth', # 'django.contrib.contenttypes', # 'django.contrib.sessions', # 'django.contrib.messages', # 'django.contrib.staticfiles', 'model_test_app', ) MIDDLEWARE_CLASSES = ( # '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', )
執行ctrl+r+syndbc時,只會根據INSTALLED_APPS設置的app來檢查
對應的數據庫表是否存在,其餘沒有設置的app不會被檢查。
3)此時數據庫中的狀態(以前有過其餘project的測試數據)
二、經過models.py定義表結構
1)models.py中錄入如下代碼:
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
以上python定義表結構涉及到的知識點:
a)字段類型:
字符串類型,URL類型,Email類型,Date類型
b)多對多關係:
authors = models.ManyToManyField(Author)
c)外鍵:
publisher = models.ForeignKey(Publisher)
d)關於主鍵:
無需顯式指明主鍵,django會自動爲每一個模型生成一個自增的整數id做爲主鍵
2)經過python在數據庫中建立表:
a)檢查model的語法和邏輯是否正確:ctrl+r+validate
b)生成建表的sql語句:ctrl+r+sql
"D:\DevPlatform\PyCharm 3.1.3\bin\runnerw.exe" C:\Python27\python.exe "D:\DevPlatform\PyCharm 3.1.3\helpers\pycharm\django_manage.py" sql model_test_app D:/ProgramData/python/model_test BEGIN; CREATE TABLE `model_test_app_publisher` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(30) NOT NULL, `address` varchar(50) NOT NULL, `city` varchar(60) NOT NULL, `state_province` varchar(30) NOT NULL, `country` varchar(50) NOT NULL, `website` varchar(200) NOT NULL ) ; CREATE TABLE `model_test_app_author` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `first_name` varchar(30) NOT NULL, `last_name` varchar(40) NOT NULL, `email` varchar(75) NOT NULL ) ; CREATE TABLE `model_test_app_book_authors` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `book_id` integer NOT NULL, `author_id` integer NOT NULL, UNIQUE (`book_id`, `author_id`) ) ; ALTER TABLE `model_test_app_book_authors` ADD CONSTRAINT `author_id_refs_id_206f10ad` FOREIGN KEY (`author_id`) REFERENCES `model_test_app_author` (`id`); CREATE TABLE `model_test_app_book` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(100) NOT NULL, `publisher_id` integer NOT NULL, `publication_date` date NOT NULL ) ; ALTER TABLE `model_test_app_book` ADD CONSTRAINT `publisher_id_refs_id_f51d29ce` FOREIGN KEY (`publisher_id`) REFERENCES `model_test_app_publisher` (`id`); ALTER TABLE `model_test_app_book_authors` ADD CONSTRAINT `book_id_refs_id_6f49ea9b` FOREIGN KEY (`book_id`) REFERENCES `model_test_app_book` (`id`); COMMIT; Process finished with exit code 0
此處多生成了一張表:model_test_app_book_authors,用於描述多對多關係
c)同步sql語句到數據庫: ctrl+r+syncdb
運行以後數據庫中的狀況:
說明:一、實際上能夠修改自動生成表名的規則
二、重複執行ctrl+r+syndbc是安全的,不會生成重複的表也不會沖掉舊數據
三、只會根據INSTALLED_APPS設置的app來檢查對應的數據庫表是否存在
三、基本數據訪問
views.py
#coding:utf-8 from django.shortcuts import render from django.shortcuts import render_to_response from model_test_app.models import Publisher # Create your views here. def db_op(request): #刪除 #Publisher.objects.filter(name='Apress').delete() Publisher.objects.all().delete() #新增 p1 = Publisher(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.', website='http://www.apress.com/') p1.save() p2 = Publisher.objects.create(name="O'Reilly", address='10 Fawcett St.', city='Cambridge', state_province='MA', country='U.S.A.', website='http://www.oreilly.com/') #更新 pub=Publisher.objects.get(name='Apress') pub.country='China' pub.save() #查詢 publisher_list = Publisher.objects.all() for publisher in publisher_list: print publisher.name,publisher.country return render_to_response('db_op.html', locals())
db_op.html:
<!DOCTYPE html> <html> <head> <title>數據庫操做</title> </head> <body> <p>操做結果:</p> <p> <ul> {% for publisher in publisher_list %} <li>{{ publisher.name }}, {{publisher.country}}</li> {% endfor %} </ul> </p> </body> </html>
執行結果:
頁面:
後臺輸出:
四、模型中的__unicode__()方法:
用於自定義輸出「模型」的字符串內容,相似於java中的toString方法
views.py中的輸出操做:
def db_op(request): #查詢 publisher_list = Publisher.objects.all() print publisher_list return render_to_response('db_op.html', locals())
未添加__unicode__()方法時:
增長了__unicode__()方法時:
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() #def __unicode__(self): #return self.name def __unicode__(self): return u'%s, %s'%(self.name,self.country)
五、關於update操做中的p.save()
並非只更新修改過的那個字段,全部的字段都會被更新
六、django中實現where條件
1)查詢中對字段進行過濾
def db_op(request): #查詢 publisher_list = Publisher.objects.filter(name='Apress',country='China') print publisher_list return render_to_response('db_op.html', locals())
執行結果:
2)like關鍵詞在django中的實現
def db_op(request): #查詢 publisher_list = Publisher.objects.filter(name__contains='eil') #publisher_list = Publisher.objects.all() print publisher_list return render_to_response('db_op.html', locals())
至關於:where name like '%eil%'
執行結果:
3)get方法獲取單條記錄:
a)剛好返回1條記錄時
def db_op(request): try: pub=Publisher.objects.get(name__contains='eil') except: print '獲取單條記錄發生異常' else: print pub.name return render_to_response('db_op.html', locals())
b)返回兩條記錄時
def db_op(request): try: pub=Publisher.objects.get(name__contains='e') except: print '獲取單條記錄發生異常' else: print pub.name return render_to_response('db_op.html', locals())
c)沒有記錄返回時
def db_op(request): try: pub=Publisher.objects.get(name__contains='eeeeeee') except: print '獲取單條記錄發生異常' else: print pub.name return render_to_response('db_op.html', locals())
4)排序
def db_op(request): #升序 publisher_list=Publisher.objects.order_by("name","country") print publisher_list #降序 publisher_list2=Publisher.objects.order_by("-name","country") print publisher_list2 return render_to_response('db_op.html', locals())
執行結果:
模型中指定默認排序規則:
class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() def __unicode__(self): return u'%s, %s'%(self.name,self.country) class Meta: ordering = ['-name']
def db_op(request): publisher_list=Publisher.objects.all() print publisher_list return render_to_response('db_op.html', locals())
執行結果:
5)where和order by同時使用
def db_op(request): publisher_list=Publisher.objects.filter(name="Apress").order_by("name") print publisher_list return render_to_response('db_op.html', locals())
6)limit的實現
def db_op(request): #返回單個記錄 pub=Publisher.objects.order_by("name")[0] print pub #返回記錄列表 publisher_list=Publisher.objects.order_by("name")[0:100] print publisher_list return render_to_response('db_op.html', locals())
執行結果:
7)更新記錄中的某些字段,而不是全部字段
使用結果集QuerySet的update()方法,而不是p.save()
def db_op(request): #返回記錄列表 affectRowCount=Publisher.objects.filter(name__contains='e').update(country='Japan') print affectRowCount publisher_list=Publisher.objects.all() print publisher_list return render_to_response('db_op.html', locals())
執行結果:
8)刪除一些記錄,而不是單條記錄
使用 使用結果集QuerySet的delete()方法,而不是先get單條p,再p.delete()
def db_op(request): #返回記錄列表 affectRowCount=Publisher.objects.filter(name='Apress').delete() print affectRowCount publisher_list=Publisher.objects.all() print publisher_list return render_to_response('db_op.html', locals())
執行結果:
ps:不會返回被刪除的行數