2018-09-12Django模型设计概念

补:运算符

(语文成绩和数学成绩均为Student类的属性)

math=models.DecimalField(max_digits=4,decimal_places=2,null=True)
chinese=models.DecimalField(max_digits=4,decimal_places=2,null=True)

用运算符实现查询语文成绩比数学成绩至少低10分的学生

stud = Student.objecects.filter(math__gtb=F('chinese') + 10)

新内容

模型设计概念:一对一,一对多,多对多的模型定义
模型设计案例:学生和学生拓展表一对一模型设计,学生和课程表多对多模型设计,学生和班级一对多模型设计

1.一对一关联(学生与学生信息)

首先在已经定义好的app文件夹中的models.py文件中定义新的类,为学生信息类

class StudentInfo(models.Model):
    phone=models.CharField(max_length=11,null=True,unique=True,verbose_name='手机号')
    address=models.CharField(max_length=50,null=True,verbose_name='地址')

    class Meta:
        db_table='student_info'

同时启动控制台Terminal来进行数据库的迁移

python manage.py makemigrations
python manage.py migrate

该类的定义要定义在Student类的前面,以免不必要的报错
然后在Student类中添加属性关联

stu_info=models.OneToOneField(StudentInfo,null=True,related_name='stu')

然后在urls.py文件中添加新的url

url('create_stu_info/',views.create_stu_info),
url('stu_add_stuinfo/',views.stu_add_stuinfo),

然后在views.py文件中定义对应的类方法,第一条url对应的类方法为为创建的学生信息类StudentInfo创建数据,第二条url则是两个类之间的关联

def create_stu_info(request):
    if request.method == 'GET':
        data = {
            '13333454561': '金牛区1',
            '13333454562': '金牛区2',
            '13333454563': '金牛区3',
            '13333454564': '金牛区4',
            '13333454565': '金牛区5',
            '13333454566': '金牛区6',
            '13333454567': '金牛区7',
            '13333454568': '金牛区8',
        }
        for k, v in data.items():
            StudentInfo.objects.create(phone=k, address=v)
        return HttpResponse('创建成功')


def stu_add_stuinfo(request):
    if request.method == 'GET':
        stu = Student.objects.get(id=7)
        # 绑定关系1:
        # stu.stu_info_id=2
        # 绑定关系2:
        stu.stu_info = StudentInfo.objects.get(id=7)
        stu.save()
        return HttpResponse('绑定学生关系')

这里暂时只考虑request.method的值为GET时的情况,这样Student类和StudentInfo类就完成1对1的绑定(get(id=x)的值相应变换代表着不同id之间的数据的绑定)

做完了绑定,就可以进行查询操作
添加新的url

url('sel_phone/',views.sel_phone),         #通过学生来查找学生信息
url('sel_stu_byphone/',views.sel_stu_byphone),      #通过学生信息来查找学生

再在views.py中定义新的类

'''
通过学生来查找学生信息
'''
def sel_phone(request):
    if request.method == 'GET':
        # 获取学生id=2的学生的手机号
        # 方法1
        # stu=Student.objects.filter(id=2).first()
        # info_id=stu.stu_info_id
        # stu_info=StudentInfo.objects.get(pk=info_id)
        # phone=stu_info.phone

        # 方法2
        stu = Student.objects.get(id=1)
        stu_info = stu.stu_info
        phone = stu_info.phone
        return HttpResponse('通过学生id查找手机号')
'''
通过学生信息来查找学生
'''
def sel_stu_byphone(request):
    if request.method == 'GET':
        stu_info = StudentInfo.objects.get(phone='13333454562')
        stu = stu_info.student
        s_name = stu.s_name
        return HttpResponse('通过手机查询学生信息')

!!!注意:其重点在于掌握一对一的绑定与查询与反向查询

2.一对多(学生与班级)

同理,在models.py文件中定义班级类Grade

class Grade(models.Model):
    g_name=models.CharField(max_length=10,unique=True,verbose_name='班级')

    class Meta:
        db_table='grade'

然后数据库迁移

python manage.py makemigrations
python manage.py migrate

在Student类中添加添加关联属性

g=models.ForeignKey(Grade,null=True,related_name='stu')

下一步就是在urls.py中添加新的url

url('create_grade/',views.create_grade),     #创建班级信息
url('sel_stu_bygrade/',views.sel_stu_bygrade),   #班级与学生信息之间的查询

最后在views.py中定义url中对应的类
中间省略了一部分内容为学生类与班级类的绑定,其实现方法有两种:
一:通过创建类来进行绑定,其原理与上面一对一中绑定关系的方法相同
二:通过navicat软件与mysql连接后手动添加(此方法更便捷)

'''
创建班级信息
'''
def create_grade(request):
    if request.method=='GET':
        # 创建班级
        data1=[
            'py1801',
            'py1802',
            'py1803',
            'py1804',
            'py1805',
            'py1806',
            'py1807',
        ]
        for x in data1:
            Grade.objects.create(g_name=x)
        return HttpResponse('创建成功')


'''
班级与学生信息之间的查询  (重点掌握查询与反向查询!!!!)
'''
def sel_stu_bygrade(request):
    if request.method=='GET':
        # 查询吴彦祖对应的班级名称
        stu=Student.objects.get(s_name='吴彦祖')
        g=stu.g
        grade=g.g_name
        return HttpResponse('通过学生姓名查班级')

        # 通过班级名查询班级内的学生信息
        g=Grade.objects.filter(g_name='py1805').first()
        stus=g.stu.all()
        stu_name1 = [(stu.s_name, stu.id) for stu in stus]
        return HttpResponse(stu_name1)

3.多对多(学生与课程)

原理同上
在在models.py文件中定义课程类Course

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

    class Meta:
        db_table='course'

然后数据库迁移(见一对一与一对多的迁移)
其次是在Student类中添加关联属性

c=models.ManyToManyField(Course,null=True,related_name='stu')

再然后就是添加url,这个也可见上面的一对一和一对多,其原理是相同的,不同的只是类方法的名字而已
最后创建类
因在数据库迁移的时候与前两种关联有区别,会产生新的关联表,所以其绑定关系的方法也与一对一和一对多有一定的区别

'''
创建课程信息
'''
def create_course(request):
    if request.method=='GET':
        # 添加课程
        data2=[
            '语文',
            '数学',
            '英语',
            '物理',
            '化学'
        ]
        for x in data2:
            Course.objects.create(c_name=x)
        return HttpResponse('创建学科成功')


'''
课程与学生之间的绑定(多对多)(重点掌握!!!!!)
'''
def create_course_stu(request):
    if request.method=='GET':
        # 添加学生对于课程的信息
        # 让id=1的学生选择课程(id=1,2)
        stu=Student.objects.get(id=1)
        # 添加add方法
        stu.c.add(1)
        return HttpResponse('添加课程成功')


        # 给数学课程和id=2的同学进行关联
        c=Course.objects.get(c_name='数学')
        stus=c.stu.add(2)
        return HttpResponse('关联成功')

        # 删除
        # stu.c.remove(2)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容