django與數(shù)據(jù)庫(kù)的運(yùn)用

前言

通過(guò)講mysql的系統(tǒng)组力,翻譯一遍,在django中通過(guò)創(chuàng)建model去和數(shù)據(jù)庫(kù)中的表進(jìn)行一一映射,并且通過(guò)ORM封裝 的處理方式去練習(xí)這一道習(xí)題琳状,并寫(xiě)出如下的解題答案

1.數(shù)據(jù)庫(kù)準(zhǔn)備

在model中定義數(shù)據(jù)庫(kù),其中的性別,男的存1盒齿,女的存0念逞。

class Student(models.Model):
    stuname = models.CharField(max_length=20)
    stusex = models.BooleanField()
    stubirth = models.DateField()
    stutel = models.CharField(max_length=255)

    class Meta:
        db_table = 'student'

2.數(shù)據(jù)庫(kù)遷移

python manage.py makemigrations
python manage.py migrate

3. 數(shù)據(jù)插入

3.1 使用表單form提交post請(qǐng)求數(shù)據(jù)
<form action="/app/addStu/" method="post">
    stuname: <input type="text" name="name">
    stusex: <input type="text" name="sex">
    stubirth: <input type="date" name="birth">
    stutel: <input type="text" name="tel">
    <input type="submit" value="提交">
</form>

3.2 獲取post請(qǐng)求困食,獲取請(qǐng)求數(shù)據(jù),并且創(chuàng)建數(shù)據(jù)
方法1:獲取類(lèi)對(duì)象進(jìn)行save()保存
stu = Student()
stu.stuname = stuname
stu.stusex = sex
stu.stubirth = birth
stu.stutel = tel
stu.save()

方法2:使用create()方法
Student.objects.create(stuname=stuname, 
                        stusex=sex,
                        stubirth=birth, 
                        stutel=tel)

方法3:使用初始化
在Student模型中重構(gòu)__init__()方法翎承,添加如下代碼

def __init__(self, name, birth=None, sex=None硕盹,tel=None):
    super().__init__()
    self.stuname = name
    self.stubirth = birth 
    self.stusex = sex
    self.stutel = tel

# 視圖函數(shù)中定義創(chuàng)建學(xué)習(xí)信息的方法為:
stu = Student('小草', 18, 1, 12331244323)
stu.save()

注意:重構(gòu)init方法的時(shí)候,一定要使用super().init()叨咖,否則會(huì)報(bào)studen對(duì)象沒(méi)有_state的屬性瘩例。

4. 查詢(xún)所有的學(xué)生信息

使用all()方法獲取所有的數(shù)據(jù)

Student.objects.all()

4. 查詢(xún)所有女學(xué)生的姓名和出生日期

Student.objects.filter(stusex=0)
或者
Student.objects.exclude(stusex=1)

其中:

filter():返回符合條件的數(shù)據(jù)

exclude():過(guò)濾掉符合條件的數(shù)據(jù)

5.查詢(xún)所有的學(xué)生,按照id從大到小排序

Student.objects.all().order_by('-id')

其中:

order_by('id'):表示按照id升序的排列

order_by('-id'):表示按照id降序的排列

6. 查詢(xún)所有的學(xué)生信息甸各,并序列化

Student.objects.all().values()
Student.objects.all().values('s_name', 's_age')

7.查詢(xún)所有80后學(xué)生的姓名垛贤、性別和出生日期(篩選)

Student.objects.filter(stubirth__gte='1980-01-01', 
                        stubirth__lte='1990-01-01')

8.查詢(xún)名字中有王字的學(xué)生的姓名(模糊),like '%小%'趣倾, like '小%'聘惦,like '%小'

Student.objects.filter(s_name__contains='小')
Student.objects.filter(s_name__startswith='小')
Student.objects.filter(s_name__endswith='小')

9.查詢(xún)id等于1,2的學(xué)生信息

# select * from student where id in (1,2)
stus = Student.objects.filter(id__in=[1,2])

10. 獲取id為1的信息,get()和filter()的使用

Student.objects.filter(id=1)
Student.objects.get(id=1)
Student.objects.get(pk=1)

# get獲取不到數(shù)據(jù)會(huì)直接報(bào)錯(cuò), filter獲取不到數(shù)據(jù)是返回空
stus = Student.objects.get(pk=5)
Student.objects.filter(id=5)

# get只能返回一個(gè)數(shù)據(jù)儒恋,返回多個(gè)會(huì)報(bào)錯(cuò)
Student.objects.get(s_age=15) # 前提條件:數(shù)據(jù)庫(kù)中s_age為15的數(shù)據(jù)有多條

11.獲取所有學(xué)生(按照id降序)中第一個(gè)/最后一個(gè)學(xué)生信息

# 獲取按照id降序的第一個(gè)學(xué)生信息
Student.objects.all().order_by('-id')[0]
Student.objects.all().order_by('-id').first()
# 獲取所有學(xué)生(按照id降序)中最后一個(gè)學(xué)生信息
Student.objects.all().order_by('-id').last()

===========模型加參===========

1.建表

class Grade(models.Model):
    g_name = models.CharField(max_length=10, unique=True, null=False)

    class Meta:
        db_table = 'grade'


class StudentInfo(models.Model):
    address = models.CharField(max_length=50, null=True)
    phone = models.CharField(max_length=11, null=True)

    class Meta:
        db_table = 'stu_info'


class Student(models.Model):
    # 長(zhǎng)度為10善绎,且唯一不能為空的姓名s_name字段  CharField - 字符串類(lèi)型
    s_name = models.CharField(max_length=10, unique=True, null=False)
    # IntegerField - 整型字段
    age = models.IntegerField(default=18)
    # auto_now_add:表示第一次創(chuàng)建數(shù)據(jù)時(shí),自動(dòng)默認(rèn)為創(chuàng)建的時(shí)間
    create_time = models.DateTimeField(auto_now_add=True)
    # auto_now: 表示修改時(shí),自動(dòng)更新為修改時(shí)間
    operate_time = models.DateTimeField(auto_now=True)
    # 是否刪除
    is_delete = models.BooleanField(default=0)
    # 定義浮點(diǎn)數(shù)總長(zhǎng)度3位,小數(shù)點(diǎn)后1位(decimal_places=1)
    yuwen = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    math = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    # 一對(duì)一:定義在關(guān)聯(lián)的兩個(gè)模型中的任何一方都可以
    stuinfo = models.OneToOneField(StudentInfo, related_name='stu', on_delete=models.CASCADE, null=True)
    # 一對(duì)多:只能定義在‘多’的一方
    grade = models.ForeignKey(Grade, related_name='stu', on_delete=models.CASCADE, null=True)

    class Meta:
        db_table = 'student'

2.數(shù)據(jù)庫(kù)遷移

python manage.py makemigrations
python manage.py migrate
模型對(duì)應(yīng)關(guān)系描述如下:

1:1 一對(duì)一 OneToOneField
1:N 一對(duì)多 ForeignKey
M:N 多對(duì)多 ManyToManyField 會(huì)自動(dòng)建一個(gè)中間表

在views.py文件中
def add_stu_info(request):
    if request.method == 'GET':
        # 向拓展表中添加信息
        stu_info = StudentInfo()
        stu_info.phone = '13545455433'
        stu_info.save()
        s_id = stu_info.id
        stu = Student.objects.filter(s_name='小明').first()
        # 第一種寫(xiě)法: 學(xué)生對(duì)象.OneToOneField字段 = 關(guān)聯(lián)對(duì)象
        stu.stuinfo = stu_info
        # 第二種寫(xiě)法: 學(xué)生對(duì)象.OneToOneField字段 = 關(guān)聯(lián)對(duì)象.id
        stu.stuinfo_id = stu_info.id
        stu.save()

        return HttpResponse('添加拓展表信息')


def sel_stuinfo_by_stu(request):
    if request.method == 'GET':
        # 通過(guò)學(xué)生信息找拓展表信息
        stu = Student.objects.get(s_name='小明')
        # StudentInfo.objects.get(pk=stu.stuinfo_id) 等價(jià)于stu.stuinfo
        # 學(xué)生對(duì)象(stu).OneToOneField字段(stuinfo)
        stu.stuinfo
        return HttpResponse('獲取拓展表信息成功')


def sel_stu_by_info(request):
    if request.method == 'GET':
        # 通過(guò)拓展表中的手機(jī)號(hào)碼找學(xué)生信息
        stuinfo = StudentInfo.objects.filter(phone='13545455433').first()
        # stu = Student.objects.filter(stuinfo=stuinfo)
        # stu = Student.objects.filter(stuinfo_id=stuinfo.id)  # 和上面一樣
        # print(stu)
        # 拓展表對(duì)象.關(guān)聯(lián)的模型名稱(chēng)小寫(xiě)
        # stu = stuinfo.student  # 和上面兩步一樣碧浊,這步很簡(jiǎn)單
        # 定義related_name參數(shù), 拓展表對(duì)象.related_name值
        stu = stuinfo.stu  # 這的stu是onetonoe字段的related_name參數(shù),它和上面那步是互斥的
        print(stu)
        return HttpResponse('通過(guò)拓展表信息查詢(xún)學(xué)生表信息')


def add_grade(request):
    if request.method == 'GET':
        # 添加班級(jí)信息, 并給學(xué)生分配班級(jí)
        names = ['Python班級(jí)', 'Java班級(jí)', 'Php班級(jí)', 'C++班級(jí)']
        for name in names:
            if Grade.objects.filter(g_name=name).exists():
                Grade.objects.creat(g_name=name)
        # 分配班級(jí)
        stus = Student.objects.filter(pk_in=[5, 6, 7, 10, 11, 12]).all()
        g = Grade.objects.filter(g_name='Python班級(jí)').first()
        for stu in stus:
            stu.grade = g
            # stu.grade_id = g.id
            stu.save()
        return HttpResponse('添加班級(jí)和學(xué)生信息')


def sel_grade_by_stu(request):
    if request.method == 'GET':
        # 通過(guò)學(xué)生查詢(xún)班級(jí)信息
        stu = Student.objects.filter(s_name='小明').first()
        g = stu.grade
        print(g)
        # 班級(jí)查詢(xún)學(xué)生
        stus = g.student_set.all()  # 和下面一樣
        stus = g.stu.all()  # 定義了related_name='stu'涂邀,
但是用了related_name之后,就不能用_set了

        return HttpResponse('通過(guò)學(xué)生查詢(xún)班級(jí)成功')

多對(duì)多

先聲明兩個(gè)類(lèi)Course, Student

class Course(models.Model):
    c_name = models.CharField(max_length=10, unique=True, null=False)

    class Meta:
        # 指定表名
        db_table = 'course'

class Student(models.Model):
    # 長(zhǎng)度為10,且唯一不能為空的姓名s_name字段  CharField - 字符串類(lèi)型
    s_name = models.CharField(max_length=10, unique=True, null=False)
    # IntegerField - 整型字段
    age = models.IntegerField(default=18)
    # auto_now_add:表示第一次創(chuàng)建數(shù)據(jù)時(shí)箱锐,自動(dòng)默認(rèn)為創(chuàng)建的時(shí)間
    create_time = models.DateTimeField(auto_now_add=True)
    # auto_now: 表示修改時(shí),自動(dòng)更新為修改時(shí)間
    operate_time = models.DateTimeField(auto_now=True)
    # 是否刪除
    is_delete = models.BooleanField(default=0)
    # 定義浮點(diǎn)數(shù)總長(zhǎng)度3位,小數(shù)點(diǎn)后1位(decimal_places=1)
    yuwen = models.DecimalField(max_digits=3, decimal_places=1, null=True)
    math = models.DecimalField(max_digits=3, decimal_places=1, null=True)

    # 多對(duì)多
    course = models.ManyToManyField(Course, related_name='stu')

    class Meta:
        db_table = 'student'

views.py文件中

def add_course(request):
    if request.method == 'GET':
        # 添加課程信息
        names = ['大學(xué)語(yǔ)文', '日語(yǔ)', '數(shù)電', '模電']
        for name in names:
            cou = Course()
            cou.c_name = name
            cou.save()

        return HttpResponse('添加課程成功')


def sel_cou_by_stu(request):
    if request.method == 'GET':
        # 查詢(xún)id為1的學(xué)生所選擇的課程信息
        stu = Student.objects.get(pk=1)
        # 學(xué)生查找課程
        stu.course

        # 課程查詢(xún)學(xué)生
        cou = Course.objexts.get(pk=1)
        cou.student_set.all()  # student是小寫(xiě)的類(lèi)名, 沒(méi)有related_name之前可以用
        cou.stu.all()
        return HttpResponse('多對(duì)多的查詢(xún)成功')


def add_del_stu_cou(request):
    if request.method == 'GET':
        # 增刪中間表的信息
        # 給小王分配'日語(yǔ)', '數(shù)電', '模電'
        stu = Student.objects.filter(s_name='小明').first()
        cou1 = Course.objects.get(c_name='日語(yǔ)')
        cou2 = Course.objects.get(c_name='數(shù)電')
        cou3 = Course.objects.get(c_name='模電')
        # 新增中間表數(shù)據(jù)
        stu.course.add(cou1)
        stu.course.add(cou2)
        stu.course.add(cou3)  # add方法加入課程(flask中用的append), 此時(shí)中間表就有信息了
        # cou1.stu.add(學(xué)生對(duì)象)  # 和上面一樣的

        # 刪除中間表數(shù)據(jù)  stu.course此時(shí)有3門(mén)課程
        stu.course.remove(cou2)
        stu.course.remove(cou3)  # 此時(shí)刪掉了數(shù)電和模電課程
        return HttpResponse('操作中間表信息成功')


def on_delete_stu(request):
    if request.method == 'GET':
        # 演示刪除, on_delete參數(shù)的效果
        stuinfo = StudentInfo.objects.get(id=6)
        stuinfo.delete()
        # models.CASCADE 表示:主鍵所在行的數(shù)據(jù)被刪, 外鍵所在行的數(shù)據(jù)也會(huì)被刪
        # models.PROTECT 表示:主鍵有對(duì)應(yīng)的外鍵數(shù)據(jù)時(shí), 不讓刪除主鍵的數(shù)據(jù)
        # models.SET_NULL 表示:主鍵刪除, 外鍵置空
        # 常用的就上面三個(gè)
        return HttpResponse('on_delete演示成功')

模型關(guān)聯(lián)關(guān)系

一對(duì)一

class A():
    id = modules.IntegerFiled()

class B():
    aa = mldels.OneToOneField(A,, on_delete=models.CASCADE, null=True,related_name='cc')
  • OneToOneField(關(guān)聯(lián)模型)
  • 模型定義
    • 關(guān)聯(lián)名 = models.OneToOneField(關(guān)聯(lián)的表名, related_name = '關(guān)系名', on_delete=models.CASCADE, null=True)
  • 已知 A 對(duì)象 a 查詢(xún) B 對(duì)象
    • 當(dāng) related_name 沒(méi)定義時(shí): a.b
    • 當(dāng) related_name = 'cc'時(shí): a.cc
  • 已知 B 對(duì)象 b 查詢(xún) A 對(duì)象 b.aa
  • 一對(duì)一:定義在關(guān)聯(lián)的兩個(gè)模型中的任意一方都可以

一對(duì)多

class A():
    id

class B():
    aa = models.ForeignKey(A, on_delete=models.CASCADE, null=True,related_name='cc')
  • ForeignKey(關(guān)聯(lián)模型)
  • 模型定義
    • aa = ForeignKey(A)
  • 已知 A 對(duì)象 a比勉,查詢(xún) B 對(duì)象
    • 當(dāng) related_name 沒(méi)定義時(shí): a.b_set
    • 當(dāng) related_name = 'cc'時(shí): a.cc
  • 已知 B 對(duì)象 b 查詢(xún) A 對(duì)象 b.aa
  • 一對(duì)多:定義在'多'的一方

多對(duì)多

  • course = models.ManyToManyField(Course 要進(jìn)行關(guān)聯(lián)的表的名字,related_name='stu') 會(huì)自動(dòng)生成中間文件,中間文件的表名為 course
  • 查詢(xún) id 為 1 的學(xué)生課程信息
  • stu = Student.objects.get(pk=1)
  • 學(xué)生查詢(xún)課程
    • stu.course
  • 課程查詢(xún)學(xué)生
    • cou = Course.objects(pk=1)
    • 當(dāng) related_name 沒(méi)定義時(shí): cou.student_set.all()
    • 當(dāng) related_name 定義時(shí): cou.stu.all()
  • 增加中間表信息
    • stu = Student.objects.filter(s_name = '小明').first()
    • cou1 = Course.objects.get(c_name='日語(yǔ)')
    • stu.course.add(cou1)
  • 刪除中間表信息
    • stu.course.remove(cou1)
  • on_delete 參數(shù)
    • models.CASCADE 表示: 主鍵所在行的數(shù)據(jù)被刪驹止,外鍵所在行的數(shù)據(jù)也會(huì)被刪
    • models.PROTECT 表示: 主鍵有對(duì)應(yīng)的外鍵數(shù)據(jù)時(shí)浩聋,不讓刪除主鍵的數(shù)據(jù)
    • models.SET_NULL 表示: 主鍵刪除,外鍵置空
  • 注意: ManyToManyFiled 定義的字段定義在任何一個(gè)關(guān)聯(lián)模型中都可以
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末臊恋,一起剝皮案震驚了整個(gè)濱河市衣洁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌抖仅,老刑警劉巖坊夫,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異撤卢,居然都是意外死亡环凿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)放吩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)智听,“玉大人,你說(shuō)我怎么就攤上這事〉酵疲” “怎么了考赛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)莉测。 經(jīng)常有香客問(wèn)我颜骤,道長(zhǎng),這世上最難降的妖魔是什么悔雹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任复哆,我火速辦了婚禮,結(jié)果婚禮上腌零,老公的妹妹穿的比我還像新娘梯找。我一直安慰自己,他們只是感情好益涧,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布锈锤。 她就那樣靜靜地躺著,像睡著了一般闲询。 火紅的嫁衣襯著肌膚如雪久免。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,584評(píng)論 1 312
  • 那天扭弧,我揣著相機(jī)與錄音阎姥,去河邊找鬼。 笑死鸽捻,一個(gè)胖子當(dāng)著我的面吹牛呼巴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播御蒲,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼衣赶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了厚满?” 一聲冷哼從身側(cè)響起府瞄,我...
    開(kāi)封第一講書(shū)人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碘箍,沒(méi)想到半個(gè)月后遵馆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丰榴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年团搞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片多艇。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖像吻,靈堂內(nèi)的尸體忽然破棺而出峻黍,到底是詐尸還是另有隱情复隆,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布姆涩,位于F島的核電站挽拂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏骨饿。R本人自食惡果不足惜亏栈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宏赘。 院中可真熱鬧绒北,春花似錦、人聲如沸察署。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贴汪。三九已至脐往,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扳埂,已是汗流浹背业簿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阳懂,地道東北人梅尤。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像希太,于是被迫代替她去往敵國(guó)和親克饶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容