# 定義模型
### 定義模型
* 在模型中定義屬性,會生成表中的字段
* django根據屬性的類型確定一下信息:
* 當前選擇的數據庫支持字段的類型
* 渲染管理表單時使用的默認html控件
* 在管理站點最低限度的驗證
* django會為表增加自動增長的主鍵列,每個模型只能由一個主鍵列,如果使用選項設置某屬性為主鍵列后,則django不會再生成默認的主鍵列
* 屬性命名限制
* 不能是python的保留關鍵字
* 由于django的查詢方式,不允許使用連續的下劃線
### 定義屬性
* 定義屬性時,需要字段類型
* 字段類型被定義在django.db.models.fileds目錄下,為了方便使用,被導入到django.db.models中
* 使用方式
* 導入from.django.db import models
* 通過models.Field創建字段類型的兌現,賦值給屬性
* 對于重要數據都做邏輯刪除,不做物理刪除,實現方法是定義isDelete屬性,類型為BooleanField,默認值為False
### 字段類型
* AutoField:一個根據實際ID自動增長的InteGErField,通常不指定。如果不指定,一個主鍵字段將自動添加到模型中
* BooleanField;true/false字段,此字段的默認表單控制是CheckboxInput
* NullBooleanField:支持null,false,true三種值
* CharField\(max\_length=字符長度\):字符串,默認的表單樣式是TextInput
* TextField:大文本字段,一般超過400使用,默認的表單控件是Textarea
* IntegerFeild:整數
* DecimalFeild\(max_digits=None,decimal\_places=None_\):使用python的decimal實例表示的十進制浮點數
* DecimalField.max\_digits:位數總數
* DecimalField.decimal\_places:小數點后的數字位數
* FloatField:用python的float實例來表示的浮點數
* DateField\[auto_now=False,auto\_now\_add=False_\]:使用python的datetime.date實例表示的日期
* 參數DateFiled.auto\_now:每次保存對象時,自動設置該字段為當前時間,用于"最后一次修改"的時間戳,總是使用當前日期,默認為false
* 參數DateFiled.auto\_now\_add:當對象第一次被創建時自動設置當前時間,用于創建的時間戳,總是使用當前日期,默認為false
* 該字段默認對應的表單控件是一個TextInput,在管理員站點添加了一個JavaScript寫的日歷控件,和一個"Today"的快捷按鈕,包含了一個額外的invalid\_date錯誤消息建
* auto-\_now-\_add,auto\_now,and default 這些設置是相互排斥的,它們之間的任何組合將會發生錯誤
* TimeFiled:使用python的datetime.time實例表示的時間,參數同DateField
* DateTimeFiled:使用python的datetime.datetime實例表示的日期和時間,參數同DateField
* FileField:一個上傳文件的字段
* ImageField:繼承了FileField的所有屬性和方法,但對上傳的對象進行校驗,確保是個有效的image
### 字段選項
* 通過字段選項,可以實現對字段的約束
* 在字段對象時通過關鍵字參數指定
* null:如果為True,Django將空值以NULL存儲到數據庫中,默認值是False
* blank:如果為True,則該字段允許為空白,默認值是False
* 對比:null是數據庫范疇的概念,blank是表單驗證證范疇的
* db\_column:字段的名稱,如果未指定,則使用屬性的名稱
* db\_index:若值為True,則在表中會為此字段創建索引
* default:默認值
* primary\_key:若為True,則該字段會成為模型的主鍵字段
* unique:如果為True,這個字段在表中必須有唯一值
### 關系
* 關系的類型包括
* Foreignkey:一對多,將字段定義在多的端中
* ManyToManyField:多對多,將字段定義在兩端中
* OneToOneField:一對一,將字段定義在任意一端中
* 可以維護遞歸的關聯關系,使用"self"指定,詳見"自關聯"
* 用一訪問多:對象.模型類小寫\_set
```text
gradesinfo.studentsinfo_set
```
* 用一訪問一:對象.模型類小寫
```text
studentsinfo.gradesinfo
```
* 訪問id:對象.屬性\_id
```text
grades.students_id
```
### 元選項
* 在模型類中定義類Meta,用于設置元信息
* 元信息db\_table:定義數據表名稱,推薦使用小寫字母,數據表的默認名稱
```text
<app_name>_<model_name>
```
* ordering:對象的默認排序字段,獲取對象的列表時使用,接收屬性構成的列表
* 字符串前加-表述倒序,不加-表示正序
* 注意:排序會增加數據庫的開銷
```text
class Grades(model.Model)
class Meta():
ordering = ['id']
ordering = ['-id']
```
## 示例演示
* 創建test2項目,并創建myapp應用,使用mysql數據庫
* 定義班級模型
```text
class gradesInfo(models.Model):
class Meta():
ordering = ['name']
name = models.CharField(max_length=20)
number = models.IntegerField()
isDelete = models.BooleanField(default=True)
```
* 定義學生模型
```text
class studentsInfo(models.Model):
class Meta():
ordering = ['name']
name = models.CharField(max_length=20)
age = models.IntegerField()
date = models.DateTimeField()
grade = models.ForeignKey('gradesInfo',on_delete=models.CASCADE)
```
```text
1.django-admin startproject project
2.python manage.py startapp myapp
3.python manage.py makemigrations
4.python manage.py migrate
5.python manage.py runserver
6.創建數據庫create database angle default charset utf8 collate utf8_general_ci;
配置數據庫:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'miku2',
'USER': 'root',
'PASSWORD': '123456',
'PORT':3306,
}
}
修改地區和時區
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
安裝mysql配置
import pymysql
pymysql.install_as_MySQLdb()
```
* 定義students、grades視圖
```text
from django.shortcuts import render
from django.http import HttpResponse
from .models import Grades,Students
# 學生信息
def students(request):
studentsList = Students.objects.all()
return render(request, 'myapp/students.html',{"students":studentsList})
# 班級信息
def grades(request):
gradesList = Grades.objects.all()
return render(request,'myapp/grades.html',{'grades':gradesList})
```
* students.html、grades.html模板
```text
students.html
"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>學生信息</title>
</head>
<body>
<h1>學生信息列表</h1>
<ul>
{% for student in students %}
<li>
{{ student.pk }} -- {{ student.sname }} -- {{ student.sgrade }}
</li>
{% endfor %}
</ul>
</body>
</html>
"""
grades.html
"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>班級表</title>
</head>
<body>
<h1>班級信息</h1>
<ul>
{% for grade in grades %}
<li>
{{ grade.pk }} -- {{ grade.gname }}
</li>
{% for student in grade.students_set.all %}
<li>學生:{{ student.sname}}</li>
{% endfor %}
{% endfor %}
</ul>
</body>
</html>
"""
```
* 配置url,能夠完成班級及學生的展示
```text
配置路由;
from django.conf.urls import url,include
from . import views
urlpatterns = [
url(r'^students/$',views.students),
url(r'^grades/$',views.grades),
]
展示省略---
```
### 測試數據
* grades的測試數據
```text
insert into myapp_grades(gname,gdate,ggirlnum,gboynum,isDelete) values
("python01","2017-2-4",10,50,0),
("python02","2017-3-6",4,34,0),
("python03","2017-4-16",12,60,0),
("python04","2017-5-4",3,75,0);
```
* students的測試數據
```text
insert into myapp_students(sname,sgender,scontend,isDelete,sgrade_id,sage)
("miku1",1,"I am miku1",0,1,25),
("miku2",1,"I am miku2",0,2,32),
("miku3",0,"I am miku3",0,1,12),
("miku4",1,"I am miku4",0,2,45),
("miku5",0,"I am miku5",0,3,7),
("miku6",1,"I am miku6",0,4,10),
("miku7",0,"I am miku7",0,2,11),
("miku8",1,"I am miku8",0,3,15),
("miku9",1,"miku9",0,1,16),
("miku10",0,"I am miku10",0,2,18),
("miku11",1,"I am miku11",0,3,18),
```