1. 程式人生 > 其它 >Django表關係與表查詢

Django表關係與表查詢

目錄 收起 1、一對多 1.1、新增資料 1.2、更新一個員工所屬的部門: 1.3、根據條件刪除: 1.4、查詢資料 2、多對多 2.1、新增資料 2.2、查詢資料 2.3、更新資料 2.4、刪除資料 3、自定義多對多表 3.1、新增資料 3.2、查詢資料 3.3、刪除資料

1、一對多

首先來說說一對多,這個關聯關係經常用到,多的一方通過models.ForeignKey進行關聯。如下示例:

class Department(models.Model):
    name = models.CharField(max_length=20)
    create_data = models.DateField(auto_now_add=True)
    is_delete = models.BooleanField(default=False)  # default=False,在資料庫中表現為0

    class Meta:
    # 這裡定義了db_table的話,那麼遷移後表名就是department這個了,不會是應用名_類名小寫(例如:framework_department)
        db_table = "department"


class Employee(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    gender = models.IntegerField(default=0)
    # decimal_place = 2表示兩位小數,max_digits表示8個數字,包括小數的兩位
    salary = models.DecimalField(max_digits=8,decimal_places=2)
    # null=True 表示可以為空,blank=True表示django後臺管理輸入這個欄位可以為空
    comment = models.CharField(max_length=300,null=True,blank=True)
    hire_data = models.DateField(auto_now_add=True)
    department = models.ForeignKey("Department")
    # department = models.ForeignKey("Department", related_name = 'employee')  # 加了related_name = 'employee'後,在進行查詢一個部門的全部員工時就不用employee_set了,直接使用employee即可。其餘方法和使用employee_set一致。

    class Meta:
        db_table = "employee"

以上定義了兩個模型,員工和部門是一對多關係,員工屬於多的一方,所以使用了models.ForeignKey來與部門進行關聯。關聯的模型如果是定義在一個py檔案裡的話,那麼可以直接寫模型名稱即可,例如:Department就可以直接使用,但是如果要關聯不在一個py檔案裡的模型,那麼就要通過:應用名.模型名使用(例如:user.User)

以上都是關於模型的定義和使用,當然,最重要的是使用模型相關方法進行增刪查改。

1.1、新增資料

新增Department:

Department.objects.create(name="生產部")

新增Employee:

Employee.objects.create(name="小明", age=18, gender=0, salary=8000.50, comment="新入職員工", department=1)

當然這樣新增會報錯:

ValueError: Cannot assign “1”: “Employee.department” must be a “Department” instance.

因為新增employee時,department需要傳入一個例項物件,而不是單純的一個ID。正確新增如下:

Employee.objects.create(name="小明", age=18, gender=0, salary=8000.50, comment="新入職員工", department=Department.objects.get(id=1))
Employee.objects.create(name="小張", age=18, gender=0, salary=9000.50, comment="新入職員工", department=Department.objects.filter(id=2)[0])

1.2、更新一個員工所屬的部門:

Employee.objects.filter(id=1).update(department=3)

這裡要注意的是,更新就不用傳一個例項物件了,只需要傳入部門id即可。傳入例項物件會報錯。

1.3、根據條件刪除:

刪除指定部門下的所有員工:

Employee.objects.filter(department=2).delete()

1.4、查詢資料

一個員工所屬的部門:

employee = Employee.objects.get(id=1)
employee_belong_department=employee.department
employee_belong_department_name= employee_belong_department.name

一個部門的全部員工:

department = Department.objects.get(id=1)
all_employee= department.employee_set.all()/a.employee_set.values()/a.employee_set.values_list()

使用外來鍵時,一般都會定義一個刪除的關聯操作。什麼意思呢?如下:

department = models.ForeignKey("Department", on_delete=models.CASCADE)

如果一個模型使用了外來鍵。那麼在對方那個模型被刪掉後,該進行什麼樣的操作。可以通過on_delete來指定。可以指定的型別如下:

CASCADE:級聯操作。如果外來鍵對應的那條資料被刪除了,那麼這條資料也會被刪除。

PROTECT:受保護。即只要這條資料引用了外來鍵的那條資料,那麼就不能刪除外來鍵的那條資料。如果我們強行刪除,Django就會報錯。

SET_NULL:設定為空。如果外來鍵的那條資料被刪除了,那麼在本條資料上就將這個欄位設定為空。如果設定這個選項,前提是要指定這個欄位可以為空。

SET_DEFAULT:設定預設值。如果外來鍵的那條資料被刪除了,那麼本條資料上就將這個欄位設定為預設值。如果設定這個選項, 前提是要指定這個欄位一個預設值 。

SET():如果外來鍵的那條資料被刪除了。那麼將會獲取SET函式中的值來作為這個外來鍵的值。SET函式可以接收一個可以呼叫的物件(比如函式或者方法),如果是可以呼叫的物件,那麼會將這個物件呼叫後的結果作為值返回回去,可以不用指定預設值 。

DO_NOTHING:不採取任何行為。一切全看資料庫級別的約束。

2、多對多

class Student(models.Model):
    name = models.CharField(max_length=16, verbose_name=u'名字')
    age = models.IntegerField(verbose_name=u'年齡')


class Club(models.Model):
    name = models.CharField(max_length=16)
    members = models.ManyToManyField("Student")

2.1、新增資料

1、首先,多對多關係表在遷移時會生成三張表,雖然我們只定義了兩張表,但是由於有ManyToManyField欄位存在,會使得第三張表名字為:有ManyToManyField欄位的模型名_欄位名(例如:club_members)。這第三張表是自動生成的,當然,我們是可以控制這第三張表,稍後會說到

新增student:

Student.objects.create(name="小張", age=19)
Student.objects.create(name="小明", age=18)
Student.objects.create(name="小銘", age=19)
Student.objects.create(name="小林", age=17)

新增club:

Club.objects.create(name="跑步")
Club.objects.create(name="跳遠")
Club.objects.create(name="跳高")
Club.objects.create(name="跳河")

club因為存在ManyToManyField欄位,所以新增資料時,不能直接將該欄位拿來使用

新增club_members:

先查詢student資料

student = Student.objects.get(name="小林")

再查詢club資料

club = Club.objects.get(name="跑步")

新增到關聯表

club.members.add(student)

注意:add()這個方法接收的是一個物件,所以,如果要進行批量新增的話,如下:

students = Student.objects.all()
club = Club.objects.get(name="跑步")
club.members.add(*students)

2.2、查詢資料

查詢一個社團的全部成員

c = Club.objects.get(name="跑步")
c.members.all()/c.members.values()/c.members.values_list()

查詢一個成員的全部社團

s = Student.objects.filter(id=1)
s.club_set.all()/s.club_set.values()/s.club_set.values_list() # 類名的小寫+_set

2.3、更新資料

更新一個club下所有成員名字為1

b=Club.objects.get(name="ww")
b.members.update(name="1")  # 返回更新條數,例如:3

2.4、刪除資料

1、ManyToManyField是預設級聯刪除的,例如,如果要刪除所有club下的某個student,那麼就很簡單了。

club=Club.objects.get(id=1) # 先查club
club.members.filter(name="ss").delete() # 再查student,name欄位是關聯的Student表的name

返回資料為:(6, {u’framework.Student’: 1, u’framework.Club_members’: 5}),表示Student表刪除了一條資料,Club_members表刪除了5條資料。如果沒有該student,那麼返回為(0, {})。從上面可以看出如果使用以上方法不僅會刪除Student表中資料,還會刪除Club表資料。

2、有時候我們不想刪除那麼多資料,例如只想刪除某個club下的所有資料而不影響Student表中資料,那麼可以使用如下方法:

club=Club.objects.get(id=1) # 先查要刪除的那個club
club.members.clear() # 呼叫clear()方法刪除所有關於該club的資料

3、有時候我們還想只刪除某個club下的某個student資料,那麼可以使用如下方法:

club=Club.objects.get(id=2) # 先查club
stu=Student.objects.get(id=2) # 再獲取要刪除的student
club.members.remove(stu) # 呼叫remove方法刪除

3、自定義多對多表

前面說了多對多會自動建立一張關聯表,這張表是可以自定義的。

class Student(models.Model):
    name= models.CharField(max_length=16)
    age = models.IntegerField()


class Club(models.Model):
    name= models.CharField(max_length=16)


class Membership(models.Model):
    student = models.ForeignKey("Student")
    club = models.ForeignKey("Club")

這種多對多關聯是自己定義的第三張關聯關係表,所以操作起來會較前面簡單。

3.1、新增資料

Membership.objects.create(student_id=1, club_id=1)

因為兩個欄位都是外來鍵關聯,所以操作時需要使用欄位名_id的形式進行操作。

3.2、查詢資料

查詢一個學生所有的club

a=Student.objects.get(id=1)
b=a.membership_set.all()

查詢一個club下的所有學生

a=Club.objects.get(id=1)
b=a.membership_set.all()

3.3、刪除資料

Membership.objects.filter(student_id=1, club_id=1).delete()

返回值:(1, {u’framework.Membership’: 1})/(0, {u’framework.Membership’: 0})


好啦,文章到這裡結束啦,謝謝瀏覽呀,祝各位看官老爺天天開心!