Django之ORM數據庫操做
1、 ORM介紹 映射關係: 表名->類名 字段->屬性 表記錄->類實例化對象 ORM的兩大功能: 操做表: - 建立表 - 修改表 - 刪除表 操做數據行: - 增刪改查 ORM利用pymysql第三方工具連接數據庫 Django沒有辦法幫助咱們建立數據庫,只能咱們本身建立好,讓Django去連接。 2、 建立表以前的準備 1) 本身建立數據庫 2) 在settings裏面配置mysql數據庫鏈接(默認爲sqllit3) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 連接數據庫的類型 'NAME': 'db', # 連接數據庫的名字 'HOST': '127.0.0.1', # 數據庫主機地址 'PORT': 3306, # 數據庫端口 'USER': 'root', # 數據庫用戶名 'PASSWORD': '123456', # 數據庫密碼 } } 注意: 這樣寫上是會報錯的,由於Django經過ORM操做數據默認是用的MySQLdb模塊(python2中的),那麼咱們須要改設置。 在app(應用)文件夾中的__init__.py問文件中加入下面兩行: import pymysql pymysql.install_as_MySQLdb() 3、 建立數據庫表 models.py from django.db import models # Create your models here. class Book(models.Model): #必需要繼承的 nid = models.AutoField(primary_key=True) #自增id(能夠不寫,默認會有自增id) title = models.CharField(max_length=32) publishDdata = models.DateField() #出版日期 author = models.CharField(max_length=32) price = models.DecimalField(max_digits=5,decimal_places=2) #一共5位,保留兩位小數 執行建立命令:(必須記住) - python3 manage.py makemigrations 建立腳本(會存到qpp目錄下的migrations文件夾中) - python3 manage.py migrate 遷移 4、 查看數據庫的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', }, } } 5、 一些小知識 1) 多對多的正反向查詢 class Class(models.Model): name= models.CharField(max_length=32,verbose_name="班級名") course = models.CharField(verbose_name="課程",max_length=32) def __str__(self): return self.name class Teacher(models.Model): name= models.CharField(max_length=23,verbose_name="姓名") classes = models.ManyToManyField(verbose_name="所屬班級",to="Class") def __str__(self): return self.name 查找登登所帶的班級 # 方式一:基於對象的查找 obj = models.Teacher.objects.filter(name="登登").first() print(obj.classes.all()) print("登登老師帶的班級",obj.classes.values("name")) # 方式二:基於雙下劃線的查找 obj_cls = models.Teacher.objects.filter(name="登登").values("classes__name") print("登登老師帶的班級",obj_cls) 注意:要說明的是多對多的查詢用.all,,查單個的時候用.values或者values_list,不要用obj.classes.name,,這樣查到的會是None,反向查詢也是如此。我就是犯了這樣的錯,引覺得戒。。 總結:無論是一對多,仍是多對多,要是查詢多得一方就得用all() 2) 例子 - 表結構 from django.db import models # Create your models here. # 一個學生有一個班級,一個班級能夠有好多學生,因此是 # 一對多的關係,關聯字段放在多的一方 class Student(models.Model): name = models.CharField(max_length=32,verbose_name="姓名") age = models.IntegerField(verbose_name="年齡") classes = models.ForeignKey(to="Class",verbose_name="所屬班級") def __str__(self): return self.name class Class(models.Model): name = models.CharField(max_length=32,verbose_name="班級名") course = models.CharField(verbose_name="課程",max_length=32) def __str__(self): return self.name class Teacher(models.Model): name = models.CharField(max_length=23,verbose_name="姓名") classes = models.ManyToManyField(verbose_name="所屬班級",to="Class") def __str__(self): return self.name 問題: - 查詢海燕所在哪一個班級 - # 方式一: - print("海燕所在的班級",models.Student.objects.filter(name="海燕").values("classes__name")) - # 方式二: - obj_cls = models.Student.objects.filter(name="海燕").first() - print("海燕所在的班級",obj_cls.classes.name) - 查詢海燕所在班的老師的姓名 print("海燕所在班的老師的姓名",models.Student.objects.filter(name="海燕").values("classes__teacher__name")) - 查詢軟件1班的全部學生的姓名 - print("軟件1班的全部學生的姓名",models.Class.objects.filter(name="軟件1班").values("student__name")) - obj = models.Class.objects.filter(name="軟件1班").first() - # print("軟件測試1班的全部學生的姓名",obj.student_set.name) #這樣打印的結果是None - print("軟件1班的全部學生的姓名",obj.student_set.all().values("name")) 重點 1、form表單中要用submit,若是用button切記要加上type,否則button默認的type是submit,會有影響 <button class="login" type="button">註冊</button> <button type="button" onclick="doValidation();">提交</button> <input type="button" onclick="doValidation();" value="提交"/> 上面兩種寫法是對的,功能同樣。 <button onclick="doValidation();">提交</button> 若是寫成這種,默認爲submit,原本doValidation方法裏有提交功能了, 再加上按鈕也是提交功能,會提交兩次。因此使用按鈕時最好指定type類型。