模型
實現需要了解一下什麼是模型,上一節已經建立過一個在models.py裏的模型了,模型在django中是一個類,通過ORM是指對象關係模型,使用模型的好處是不需要自己去寫原生的sql語句,django會根據你的數據庫生成對應的sql並生成響應的表,因此可移植性高。下面是一個簡單的例子。
在app/models.py寫入內容如下
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
在pycharm中執行遷移
python manage.py makemigrations
python manage.py migrate
數據庫中查詢
mysql> show tables;
+----------------------------+
| Tables_in_web |
+----------------------------+
| app_person |
| app_user |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.00 sec)
mysql> describe app_person;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| first_name | varchar(30) | NO | | NULL | |
| last_name | varchar(30) | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
生成了一個表 app_person,查看錶的字段,是由三個字段,id first_name last_name,這裏後兩個字段是我們自己創建的,第一個字段是自動生成的表示主鍵,因此如果我們不特殊指定主鍵會自動生成一個名爲id的主鍵,自動創建的字段如果不特殊指定名字爲創建類的字段名,當然我們也可以指定字段名。下面來介紹。
from django.db import models
class Person(models.Model):
first_name = models.CharField(db_column='first',max_length=30)
last_name = models.CharField(db_column='last',max_length=30)
mysql> describe app_person;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| first | varchar(30) | NO | | NULL | |
| last | varchar(30) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
字段選項
通用選項
null
blank
default
primary_key
unique
可指定null=true表示可以不插入值是與數據有關的,blank=true表示可以在驗證表單時表單爲空,但是插入數據必須有值。
例子:
class Person(models.Model):
first_name = models.CharField(db_column='first',max_length=30,null=True)
last_name = models.CharField(db_column='last',max_length=30,blank=True)
mysql> describe app_person;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| first | varchar(30) | YES | | NULL | |
| last | varchar(30) | NO | | NULL | |
mysql> insert into app_person(last) values('sun');
Query OK, 1 row affected (0.01 sec)
可以看到first可以不插入值,
default字段可以指定一個字段的默認值,有了默認值如果不插入字段可以使用默認的值而不會出錯。
primary_key=True表示指定一個字段爲主鍵,自己指定主鍵後,django便不會自動生成主鍵,指定
id = models.AutoField(primary_key=True)和django默認生成的時一樣的
unique指定一個字段爲唯一的,如果插入重複的值會報錯
數據庫關係模型
三種關係模型:
一對一
多對一
多對多
一對一:這種關係模型很常用,比如在當想要擴充一個表但是不想修改一個表結構時可以創建一個新的表,使用一對一的關係關聯起來,這種關係可以一對一的將表關聯起來,下面是一個例子,有兩個表用戶表和電話號碼錶,假設一個人有一個電話號碼,一個電話只能屬於一個人。
爲了防止數據庫表重名將web數據庫和migrations下的遷移記錄刪除,重新創建。
from django.db import models
# Create your models here.
class Phone_Number(models.Model):
number=models.CharField(max_length=11)
register_data=models.DateTimeField(auto_now_add=True)
class User(models.Model):
username=models.CharField(max_length=20)
address=models.CharField(max_length=100)
phone=models.OneToOneField(Phone_Number,on_delete=models.CASCADE)
執行遷移
現在介紹一個工具django的shell工具
在命令行裏輸入python manage.py shell便可進入django的shell環境。然後將模型裏面的類導入
(venv) C:\Users\Administrator\PycharmProjects\webproject\web>python manage.py shell
Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app.models import Phone_Number,User 導入類
>>> phone=Phone_Number() 創建一個phone類對象
>>> user=User() 創建一個user類對象
>>> phone.number='1324456763' 給對象賦值
>>> phone.save() 將phone對象的內容更新到數據庫 這一步纔會將phone更新到數據庫
>>> user.username='sun'
>>> user.address='china'
>>> user.phone=phone
>>> user.save()
>>>
來看看我們的數據庫
mysql> select * from app_user;
+----+----------+---------+----------+
| id | username | address | phone_id |
+----+----------+---------+----------+
| 1 | sun | china | 1 |
+----+----------+---------+----------+
1 row in set (0.00 sec)
mysql> describe app_user;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(20) | NO | | NULL | |
| address | varchar(100) | NO | | NULL | |
| phone_id | int | NO | UNI | NULL | |
+----------+--------------+------+-----+---------+----------------+
mysql> select * from app_phone_number;
+----+------------+----------------------------+
| id | number | register_data |
+----+------------+----------------------------+
| 1 | 1324456763 | 2020-05-30 02:28:49.513789 |
+----+------------+----------------------------+
1 row in set (0.00 sec)
看app_user表結構 phone_id是我們創建的一對一關係的外鍵 約束時unique的 因此當我們再次綁定一個數據會報錯
mysql> insert into app_user(username,address,phone_id) values('zhang','china',1);
ERROR 1062 (23000): Duplicate entry '1' for key 'app_user.phone_id'
多對一:多對一關係比較常用,下面舉一個例子,班級學生,一個班級有多個學生,每個學生只屬於一個班級
class Class(models.Model):
num=models.CharField(max_length=10)
count=models.IntegerField()
class Student(models.Model):
name = models.CharField(max_length=10)
age = models.IntegerField()
clsss = models.ForeignKey(Class,on_delete=models.CASCADE)
多對多:
class Student(models.Model):
name = models.CharField(max_length=10)
age = models.IntegerField()
clsss = models.ForeignKey(Class,on_delete=models.CASCADE)
class Course(models.Model):
name = models.CharField(max_length=20)
grade_point = models.IntegerField()
class SC(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE, related_name='student')
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='course')
grade = models.IntegerField()