Django數據庫主表從表


一對多

models.py

from django.db import models

# Create your models here.

# 數據庫:一對多。它指的是兩個表之間的關系,一指的是主表中的一條數據,多指的是從表中的多條數據。
# 兩個表:
# 班級表(1班,2班,3班)
# 學生表(張三-1班, 李四-1班, 王五-1班,趙六-2班,麻子-3班,小明-2班)
# 這兩個表:班級表就是主表,因為班級表的一條數據(比如1班)對應了學生表的多條數據(張三-1班, 李四-1班, 王五-1班),所以學生表是從表。

class Classes(models.Model):
    """
    這是班級表,是主表;
    """
    c_name = models.CharField(max_length=20)

    class Meta:
        db_table = 'classes'

class Student(models.Model):
    """
    這是從表,學生表;
    主表中的一條數據可以對應從表中的多條數據;
    從表中的一條數據只能對應主表中的一條數據;
    """
    s_name = models.CharField(max_length=20)

    # 如何在從表中關聯主表的ID?
    # ForeignKey()外鍵,在Student表中,關聯外部表Classes的主鍵,所以稱為外鍵。
    # on_delete:必須設置。表示從表數據所關聯的主表數據被刪除以后,從表應該怎么辦。
    # 1. CASCADE:如果主表數據刪除,從表對應的數據也全部刪除;
    # 比如:張三、李四、王五關聯的都是1班,如果1班這條數據被刪除了,那么,對應的張三、李四、王五也全部刪除;
    # 2. SET_NULL:如果主表數據刪除,從表數據保留,但是這種外鍵的關聯關系classes_id設置為NULL。

    # 從表關聯兩個主表的外鍵。
    # related_name指定外鍵的關聯名稱,這個名稱是用於將來查詢數據使用的。只在主表查從表時會用到。
    classes_one = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name='cls_one')
    classes_two = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name='cls_two')


    class Meta:
        db_table = 'student'

 

views.py

from django.shortcuts import render
from django.views.generic import View
from .models import Classes, Student

# 通用視圖類的用法:
# 1. 主要作用還是用於配置url路由,只不過形式和視圖函數的寫法不一樣,但是功能是一樣的;視圖函數區分GET和POST主要是通過request.method,而通用視圖將GET和POST請求封裝成了類中的兩個方法;

class Home(View):
    def get(self, request, id):
        print('------', id)
        """
        self和request是固定的兩個參數,這兩個參數后面如果還有參數,那就是url傳遞的參數;
        :param request:
        :return:
        """
        return render(request, 'index.html')

    def post(self, request, id):
        print('=======', id)
        a = request.POST.get('a')
        b = request.POST.get('b')

        return render(request, 'index.html', {'result': int(a)+int(b)})

class DataHandler(View):
    def get(self, request):

        # 數據庫中要先存在主表的數據,然后才能創建從表的數據。
        # c1 = Classes(c_name='1班')
        # c1.save()
        # c2 = Classes(c_name='2班')
        # c2.save()
        # c3 = Classes(c_name='3班')
        # c3.save()

        # 關聯主表id:通過classes(表面)或者classes_id(核心)都可以進行綁定;
        # s1 = Student(s_name="張三", classes_one=c1, classes_two=c1)
        # s1.save()
        # s2 = Student(s_name="李四", classes_id=c1.id)
        # s2.save()
        # s3 = Student(s_name="王五", classes=c2)
        # s3.save()
        # s4 = Student(s_name="趙六", classes_id=c3.id)
        # s4.save()

        # return render(request, 'index.html')

        # 如何根據主表的一條數據查詢所有從表的數據?
        c1 = Classes.objects.get(id=1)
        # 語法:主表數據.從表名稱_set
        # student_set就是一個查詢結果集,所有的學生數據都在里面。
        # stus = c1.student_set.all()

        # 如果從表出現,多個關聯同一個主表的外鍵,就不能再使用student_set了,無法區分是classes_one還是classes_two。
        stus = c1.cls_two.all()

        # 如何根據從表的一條數據查詢對應的一條主表的數據?
        s1 = Student.objects.get(id=1)
        # classes就是s1對象的屬性,是在Student類中聲明的一個屬性。
        classes_name = s1.classes_two.c_name

        return render(request, 'index.html', {'stus': stus})

 

一對一

models.py

from django.db import models

# Create your models here.
# ORM數據庫的一對一關系:一個表中的一條數據對應着另外一個表中的一條數據。
# 例如: 一個賬戶只對應着一個聯系人,一個聯系人只能有一個賬戶。身份證。

class Account(models.Model):
    """
    一個賬戶類
    """
    # 賬戶名稱
    a_name = models.CharField(max_length=20)
    # 賬戶密碼
    a_pwd = models.CharField(max_length=100)
    # 賬戶激活的時間
    # DateField()參數為空,這個字段的值需要自己添加。
    # auto_now=True: 當這個Account這個對象的屬性被修改了,在保存的時候,這個a_register_date這個時間會自動更新為保存時間;(強調更新時間)
    # auto_now_add=True: 含義就是這個時間字段,不會隨着對象的修改而更新這個時間,只在這個對象被第一次創建的時候自動填充創建的時間。以后也不會再變動了。(強調創建時間)
    # auto_created=True: 表示使用當前時間作為值,自動創建這個字段的值。默認是False。當創建對象的時候就不需要給這個字段賦值了,會自動創建。
    a_register_date = models.DateTimeField(auto_now_add=True, auto_created=True)
    a_update_date = models.DateTimeField(auto_now=True)
    class Meta:
        db_table = 'account'


class Contact(models.Model):
    """
    一個賬戶的擁有人。
    """
    # 所有人的姓名
    c_name = models.CharField(max_length=20)
    # 所有人的住址
    c_address = models.TextField()
    # 所有人的聯系方式
    c_phone = models.CharField(max_length=20)

    # 添加賬戶和所有人的一對一關系。
    # models.CASCADE:當account表中的一條數據刪除時,對應的contact表中的數據也要刪除。
    account = models.OneToOneField(Account, on_delete=models.CASCADE)

    class Meta:
        db_table = 'contact'

# 將models.OneToOneField寫在哪一個表中,哪一個表就是從表;OneToOneField()的第一個參數就是主表;
# OneToOneField不強調位置關系,兩個表中任選一個作為主表,另一個作為從表;

# 一對多:一必須是主表,多是從表,強調位置關系。

views.py

from django.shortcuts import render
from .models import Account, Contact
from datetime import datetime

def add(request):
    # 添加主表數據
    a1 = Account(a_name='1@qq.com', a_pwd='123', a_register_date=datetime.now(), a_update_date=datetime.now())
    a1.save()
    a2 = Account(a_name='2@qq.com', a_pwd='456', a_register_date=datetime.now(), a_update_date=datetime.now())
    a2.save()
    # 添加從表數據
    c1 = Contact(c_name='張三', c_address='北京', c_phone='111', account=a1)
    c1.save()
    c2 = Contact(c_name='李四', c_address='鄭州', c_phone='222', account_id=a2.id)
    c2.save()

    return render(request, 'index.html', {'result': '數據添加成功'})

def select(request):
    # 根據主表的一條數據,查詢從表的一條數據。也就是查詢該賬戶的擁有人。
    account = Account.objects.get(id=2)
    contact = account.contact.c_name
    # 根據從表的一條數據,查詢主表的一條數據。也就是查詢這個人的賬戶。
    contact = Contact.objects.get(id=2)
    account = contact.account.a_name
    return render(request, 'index.html', {'data': account})


def update(request):
    account = Account.objects.get(id=1)
    account.a_pwd = '111'
    account.save()

    return render(request, 'index.html', {'result': '數據修改成功'})


def delete(request):
    Account.objects.get(id=1).delete()
    return render(request, 'index.html', {'result': '數據刪除成功'})

 

多對多

models.py

from django.db import models

# Create your models here.

# 多對多:一個表中的一條數據對應另外一個表中的多條數據;另外一個表中的一條數據對應着前一個表中的多條數據;

class Publication(models.Model):
    """
    出版社(主表)
    """
    p_name = models.CharField(max_length=50)


class Article(models.Model):
    """
    文章(從表)
    """
    a_name = models.CharField(max_length=50)
    pub = models.ManyToManyField(Publication)


# 一對多:ForginKey一定要設置在從表。
# 一對一和多對多:關系可以設置在任意一個表中。

views.py

from django.shortcuts import render
from .models import *
from django.http import HttpResponse
# Create your views here.

def index(request):
    # 添加
    # 一對一和一對多:先添加主表的數據,再添加從表的數據;
    # 多對多:先分別添加兩個表的數據,然后再進行關聯;
    # p1 = Publication(p_name='新華出版社')
    # p1.save()
    # p2 = Publication(p_name='東方出版社')
    # p2.save()
    #
    # a1 = Article(a_name='個稅改革')
    # a1.save()
    # a2 = Article(a_name='大橋通車')
    # a2.save()

    # 關聯文章和出版社的關系
    # a1這個文章關聯的出版社是p1和p2,意思就是p1和p2兩個出版社都出版了a1這個文章。
    # a1.pub.add(p1, p2)
    # a2.pub.add(p2)

    # 查詢:
    # 1-根據主表數據查詢從表數據;
    # 查詢 "東方出版社" 出版過的所有文章;
    p1 = Publication.objects.get(id=2)
    articles = p1.article_set.all()
    for article in articles:
        print(article.a_name)
    # 2-根據從表數據查詢主表數據;
    # 查詢 "個稅改革" 這個文章,共有幾個出版社出版;
    a1 = Article.objects.get(id=1)
    pubs = a1.pub.all()
    for p in pubs:
        print(p.p_name)

    return HttpResponse('數據添加成功')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM